2015 · Media player · Apple

iPod touch (6th generation)

A transactional native host on a 320×568 surface, 60 Hz from a run-loop timer.

Hardware-tested hostGuest · QuickJS + native corehosts/ipodtouch/

The sixth-generation iPod touch was the last iPod with a touchscreen and the only one with a 64-bit chip: an A8 at 1.1 GHz, 1 GB of RAM and a 4-inch 640×1136 Retina display in an 88-gram body. It launched in July 2015 and ended on iOS 12.

The PocketJS host is an arm64 UIKit application that statically links engine/apple and advances the guest from an explicit 60 Hz main-run-loop timer, because the tested jailbroken iOS 12 runtime does not deliver CADisplayLink callbacks. The 568-point height exceeds the legacy touch wire's 9-bit range, so the host emits the framework's wide touch form.

Processor
Apple A8 · 1.1 GHz
Memory
1 GB
Display
640 × 1136 Retina
A space-grey sixth-generation iPod touch, front view
A space-grey sixth-generation iPod touch, front view. Photo: Redolta · CC0 · The fifth and sixth generations share the same body.
01

Hardware

curated here · sources below

Compute

SoC
Apple A8 (APL1011) with M8 motion coprocessor
CPU
Dual-core 64-bit ARMv8 “Typhoon”, 1.1 GHz
GPU
PowerVR GX6450, 4 clusters
RAM
1 GB LPDDR3
Storage
16 / 32 / 64 / 128 GB

Display & input

Display
4″ IPS LCD “Retina”, 640 × 1136, 326 ppi
Touch
Capacitive multi-touch
Cameras
8 MP iSight with 1080p video; 1.2 MP FaceTime
Sensors
3-axis gyroscope, accelerometer

Connectivity

Wireless
Wi-Fi 802.11a/b/g/n/ac, Bluetooth 4.1
Ports
Lightning, 3.5 mm
Battery
1043 mAh

Body

Dimensions
123.4 × 58.6 × 6.1 mm
Weight
88 g
Released
15 July 2015
OS
iOS 8.4 → 12.5.7 (final); PocketJS tested on 12.5.8 (16H88)
02

PocketJS on this machine

Guest · QuickJS + native core

What runs

bun ipodtouch build resolves apps/ipodtouch-demo/pocket.json, builds its Solid guest and pak, compiles pocket-apple for arm64 iOS 12, links a UIKit executable and pseudo-signs it with ldid. The host publishes ipodtouch-dev / ABI 7 — a plan-built guest refuses to mount on a host with a different target identifier. Each deploy re-identifies the USB device, opens a fresh UDID-scoped tunnel to Checkra1n's Dropbear on port 44, verifies the staged bundle byte by byte and keeps a rollback copy until SpringBoard registration succeeds.

What is proven

Runtime acceptance requires a live PID, advancing guest frames, an error-free receipt, a completed touch sequence and a changed hero_tap action; capture pulls the device-rendered frame. Tested device: iPod7,1 on iOS 12.5.8 — a private development profile.

Record

  1. Native PocketJS device host for the iPod touch lands (PR #278).

  2. v0.10.1

    The sixth-generation iPod touch has a transactional native host with a device receipt proving frames, release and hero_tap.

Profile · as declared by the demo manifestsource ↗
Profile
ipodtouch-dev
Logical viewport
320 × 568
Physical viewport
640 × 1136
Raster density
Requires
  • input.touch
  • text.glyphs.baked
03

Example code

upstream source · highlighted at build time
apps/ipodtouch-demo/app.tsxtsx · 15 lines · @6c43f49

The 320×568 touch demo.

import { runEffect } from "@pocketjs/framework/effects";
import Hero from "../hero/app.tsx";

export default function IPodTouchHero() {
  return (
    <Hero
      actionLabel="Tap Hero"
      deviceLabel="running on a 2015 iPod touch."
      headline="JSX on A8."
      onAction={(count) => runEffect("ipodtouch.hero_tap", { count }, () => {})}
      presentationHz={60}
      runtimeLabel="RUST + QUICKJS + UIKIT"
    />
  );
}
04

Bring-up guide

upstream documents · rendered verbatim

Toolchain, build, deploy and acceptance are owned by pocket-stack/pocketjs. The documents below are rendered from the pinned checkout without edits; relative links point back into the repository at the same revision.

iPod touch 6 connected-device host

4 min read · 854 words

Execution path, build and deploy, app icon, hardware acceptance.

rendered verbatim fromdocs/IPODTOUCH.md@ 6c43f49raw ↗

PocketJS runs on the sixth-generation iPod touch as a native UIKit application. The tested device is iPod7,1 on iOS 12.5.8 (16H88) with an A8 processor and a 640×1136 Retina display. The host exposes a 320×568 logical viewport at raster density 2.

Execution path

The application statically links engine/apple:

  • pocket-mod owns the QuickJS guest realm.
  • pocket-ui-surface installs the synchronous ui.* operations and feeds the baked asset package.
  • pocketjs-core lays out and software-rasterizes the draw list.
  • PocketSurfaceView advances the guest from a 60 Hz main-run-loop timer, presents the framebuffer through Core Graphics, and maps UIKit touches back to logical coordinates. The iPod host selects this explicit clock because its jailbroken iOS 12 runtime does not deliver CADisplayLink callbacks; the default Apple host keeps the display-link path.

The iPod host publishes ipodtouch-dev / ABI 7. The NativeScript simulator shell continues to publish ios-dev / ABI 7. A plan-built guest refuses to mount when the target identifier differs, even though both hosts share the same operation ABI.

Build and deploy

The host requires Xcode, Rust's aarch64-apple-ios target, Bun dependencies, ldid, libimobiledevice, and a Checkra1n-jailbroken device. Checkra1n exposes Dropbear only through usbmux device port 44 in this workflow. The local tunnel defaults to 127.0.0.1:2223; it does not open a Wi-Fi listener.

rustup target add aarch64-apple-ios
bun install --frozen-lockfile
bun ipodtouch doctor
bun ipodtouch build
bun ipodtouch deploy
bun ipodtouch launch

build resolves apps/ipodtouch-demo/pocket.json, builds its Solid guest and pak, compiles pocket-apple for arm64 iOS 12, links a UIKit executable, and pseudo-signs it with ldid. Generated output is dist/ipodtouch/PocketJSiPod.app. The build ID hashes the compiled libpocket_apple.a in addition to the guest and host inputs, so any transitive native-code change produces a different device receipt.

deploy performs these checks before replacing the installed bundle:

  1. Re-identify the USB device as the exact tested model, system version, build, and activated state.
  2. Start a new iproxy tunnel bound to that UDID and verify the jailbreak's SSH host key with the dedicated key in ~/.cache/pocket-stack/ipodtouch/keys. Deploy, launch, status, and capture never reuse an existing local tunnel.
  3. Acquire a device-side deployment lock and extract through transaction-unique archive, unpack, stage, and backup paths.
  4. Verify the staged executable's pseudo-signature and compare every recorded file with its local SHA-256 hash.
  5. Rename the old bundle to its transaction backup, commit the stage, set ownership, verify the executable, and register the exact bundle with uicache. The prior bundle is deleted only after every post-install check succeeds; any earlier failure restores and re-registers it.

The installed path is /Applications/PocketJSiPod.app. The command does not modify activation, firmware, root filesystem mounts, jailbreak packages, or other applications.

While the dedicated demo is active, the host disables the application idle timer. If iOS reports a near-zero display brightness when the app becomes active, the host restores it to 60 percent. The host re-enables normal idle behavior when it enters the background. The runtime receipt records both the observed brightness and idle-timer state.

App icon

hosts/ipodtouch/Icon.svg is the only authored icon source. It uses the Pocket homepage's #05070d, #070a11, and #101827 dark surfaces with restrained #60a5fa and #22d3ee iOS 7-style ambient highlights. There is no baked outer frame; SpringBoard applies the installed rounded mask. The centered light mark preserves the exact compact Pocket geometry from site/assets/favicon.svg. tools/ipodtouch-icon.ts rasterizes that SVG into the 57, 114, 120, and 180-pixel iOS PNG names and produces the opaque 4-inch launch images. For each output, the rasterizer asks the SVG renderer for an eight-times target-sized vector raster and reduces each 8 x 8 sample block with an exact area average. The small mark uses gradients without SVG filters, clipping, or fractional inner strokes, so curved internal edges are sampled once and remain antialiased at 57 pixels. No generated PNG is committed. The bundle receipt hashes every baked file that deployment reads back from the device.

Hardware acceptance

After launch, the app writes /private/var/tmp/pocketjs-ipodtouch.status.json. The receipt contains the build identity, PID, guest frame counter, screen geometry, completed touch sequences, the most recent application action, and any runtime error.

bun ipodtouch status
# Tap and release the blue Hero action on the iPod.
bun ipodtouch status --require-action
bun ipodtouch capture

The action-level check accepts only hero_tap with a positive value after a completed touch sequence. capture copies the device-rendered UIKit frame to dist/ipodtouch/device-frame.png for visual inspection. A successful build, bundle copy, icon registration, or launch request is not a rendered-frame and input receipt.

The 320 x 568 logical surface exceeds the legacy touch wire's 9-bit Y range. The Apple host emits the framework's wide 10-bit touch form for this surface, so the bottom action remains hittable instead of being clamped to Y=511. At the down edge, the Apple core resolves the committed-frame bounds hit once and carries that hit fact beside the contact as frame() argument 4 until release.

The jailbreak is semi-tethered: after a full reboot, run Checkra1n again before using deploy or launch. The installed app and dedicated SSH public key remain on the data volume, but the USB Dropbear endpoint is unavailable until the jailbreak is active again.

Photo

Wikimedia Commons · IPod 6th Generation.jpg — Redolta, CC0. The fifth and sixth generations share the same body.