Skip to content

rs/appclipcode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

App Clip Codes, Reverse Engineered

appclipcode provides Go and JavaScript/TypeScript implementations of Apple's App Clip Code format.

Apple ships those circular App Clip Codes, but does not document the format. This repo reverse engineered the full pipeline and rebuilt it in JavaScript and Go.

The JS lib can generate App Clip Codes directly in the browser. The Go version can generate, decode, and scan them from images. Both match Apple's generator on accepted URLs.

It can:

  • generate App Clip Code SVGs from accepted https:// URLs
  • reproduce Apple's URL compression bit-for-bit for generator-accepted URLs
  • render the circular code, including palette templates
  • decode URLs back from SVGs
  • decode from raster images through the CLI and ReadImage

The reverse-engineering write-up lives in doc/SPEC.md.

Why I Built This

I got interested in this while working on App Clip invocation flows.

Ever played a Netflix game on a TV and paired your phone as the controller? That seamless pairing flow used an App Clip on iPhone, but the code on screen had to be a normal QR code because the controller device might be Android and App Clip Codes are Apple-only. Each pairing session needed its own invocation URL, so the QR code had to be generated dynamically.

Later I was prototyping an iPhone-only install-and-configure flow for NextDNS. Same general problem, but without the cross-platform constraint. A QR code would still have been perfectly sufficient. That made App Clip Codes completely unnecessary and therefore irresistible.

That turned into a reverse-engineering project.

Implementations

This repository currently includes two implementations:

  • Go: the main library and CLI in the repository root, with generation, SVG decoding, and raster-image scanning support
  • JavaScript / TypeScript: the package in js/, focused on the encoder path and SVG generation, usable directly in the browser, with a local appclipcode CLI

What Was Hard

Rendering the rings was the easy part. The hard part was matching Apple's actual encoding and validation rules:

  • host format selection
  • template-word paths
  • combined vs segmented non-template encoding
  • segmented path/query subtype selection
  • generator-compatible URL validation
  • the 128-bit payload limit

In the end, the format turned out to be a mix of fairly standard building blocks, especially multi-context Huffman coding driven by Apple-trained frequency tables, combined with very Apple-specific host tables, path wordbooks, and URL acceptance rules.

Those constraints are also why App Clip Codes are not a very good generic QR code replacement: they are iOS-only, accept only a narrow subset of URLs, and depend on a compression scheme with a tight payload budget plus App Clip-specific frequency tables, host tables, and wordbooks.

LLMs and Reverse Engineering

The LLMs did most of the brute-force exploration. My job was to decide what to test next, supply hypotheses, reject fake progress, and turn the result into a sound implementation. The loop was fairly mechanical: use Apple's generator as the oracle, generate lots of examples, diff outputs, propose a rule, then try to break it with tests.

Claude with Opus 4.6 1M got about halfway there and then failed in a very instructive way. Instead of recovering the missing behavior, it introduced a large hardcoded table of precomputed encodings and then tried to validate the result with tests derived from those same hardcoded answers. It looked like progress until it had to explain what it was actually doing.

Codex with GPT-5.4 at high reasoning was much better at closing the gap. My takeaway is that LLMs can be genuinely useful for reverse engineering if they are doing hypothesis generation under a test harness. Left alone, they are also perfectly capable of building an impressive-looking lie.

Status

The generator path is reverse engineered and matches Apple's AppClipCodeGenerator for accepted URLs.

That includes:

  • host format selection
  • template-word paths
  • combined vs segmented non-template encoding
  • segmented path/query subtype selection
  • generator-compatible URL validation and the 128-bit payload limit

Getting Started

Go

Install:

go get github.com/rs/appclipcode
go install github.com/rs/appclipcode/cmd/appclipcodegen@latest

CLI example:

appclipcodegen gen https://example.com -o code.svg

More details: doc/GODOC.md

JavaScript / TypeScript

Install:

npm install appclipcode

CLI example:

npx appclipcode https://example.com --index 0 -o code.svg

The JS library can also run directly in the browser; only the CLI is Node-specific.

More details: js/README.md

Reverse-Engineering Notes

The full write-up is in doc/SPEC.md.

Some of the more useful findings:

  • SPQ and CPQ are standard trie-context Huffman coders
  • the non-template selector is 0 = combined, 1 = segmented
  • segmented mode is a real grammar with typed path and query components
  • host format 1 uses a much larger fixed-TLD table than early partial extraction suggested
  • the generator validates URL text differently from raw URLCompression.framework
  • AppClipCodeGenerator rejects URLs whose compressed payload exceeds 128 bits, even though the lower-level framework can emit longer raw bitstreams

License

This project is licensed under the MIT License. See LICENSE.

Disclaimer

This project is an independent, unofficial implementation of the App Clip Code format. It is not affiliated with, authorized by, endorsed by, sponsored by, or otherwise approved by Apple Inc.

Apple, App Clips, and App Clip Code are trademarks of Apple Inc., registered in the U.S. and other countries and regions.

About

App Clip Code Reverse Engineered

Resources

License

Stars

Watchers

Forks

Packages