For developers
Build from source
Cra is a Swift package around Chromium Embedded Framework. One script does the whole build.
Requirements
- macOS 14 or later on Apple silicon. The fetch script pins the arm64 CEF build; Intel is on the roadmap.
- Xcode 16 or later, for the Swift 5.10 toolchain and the macOS 14 SDK.
- CMake, for the CEF C++ wrapper:
brew install cmake. - About 1 GB of disk for the CEF distribution and build products.
Build and run
git clone https://github.com/VictorKildahl/cra.git
cd cra
scripts/build.sh # first run fetches CEF (about 130 MB) and builds its wrapper
scripts/run.sh # builds if needed, then opens build/Cra.app
scripts/dev.sh # dev loop: rebuilds and relaunches on savescripts/build.sh debug makes a debug build. scripts/run.sh --rebuild forces a rebuild before launching. scripts/dev.sh keeps a debug CraDev.app running and rebuilds it in a few seconds whenever a source file changes.
What the build script does
- Runs
scripts/fetch-cef.sh, which downloads the pinned CEF binary distribution intovendor/cefand buildslibcef_dll_wrapperwith CMake. Both steps are skipped when already done. - Runs
swift buildfor the three targets:Cra(the app),CraCEF(the Objective-C++ bridge) andCraHelper(the Chromium subprocess). - Stages
Cra.appwith the framework and five helper apps, one per Chromium process type: default, Alerts, GPU, Plugin and Renderer. - Ad-hoc signs everything, innermost first, then syncs the bundle into
build/Cra.appso LaunchServices keeps treating it as the same app.
Environment variables
| Variable | Default | Purpose |
|---|---|---|
CRA_VERSION | 0.1.0 | Marketing version written into Info.plist |
CRA_BUILD | timestamp | Build number written into Info.plist |
CEF_VERSION | pinned in the script | Which CEF distribution to fetch |
CEF_ARCH | macosarm64 | CEF architecture to fetch |
Layout
Sources/Cra | The app: model, store, sidebar, command bar, windows, split view, import, settings |
Sources/CraCEF | Objective-C++ bridge between Swift and CEF |
Sources/CraHelper | Chromium subprocess executable |
docs/arc-reverse-engineering.md | What was learned from Arc’s data files and how |
brand/ | Logo assets |
resources/blocklist | The ad and tracker domain list, with its licence notices |
vendor/cef | CEF distribution, fetched, not committed |
Scripting the running app
Cra registers the cra:// scheme, which is handy for testing without touching the keyboard:
open "cra://action/newTab" # any action id from the shortcuts page
open "cra://commandbar?query=github" # open the command bar with text
open "cra://open?url=https://example.com&background=1"
open "cra://open?url=https://example.com&little=1" # in a Little Window
open "cra://import?source=arc&archive=1&settings=1"
open "cra://dismiss" # close sheets, command bar, find barData
Everything lives in ~/Library/Application Support/Cra: the sidebar and archive as JSON, keybindings.json, cached favicons, chromium.log, and a Chromium profile folder. Delete it to start over. See privacy for the full list.