tobi ~/t/fizzy ❯❯❯ scint install
💎 Scintellating Gemfile into ./.bundle (scint 0.7.1, ruby 4.0.1)
Fetching index https://rubygems.org
162 gems installed total (162 cached). (1.42s, 15 workers used)
Scint is an experimental Bundler replacement. Pure Ruby, no dependencies.
It reads your Gemfile and Gemfile.lock, writes standard Gemfile.lock, and materializes into .bundle/ so bundle exec keeps working. Same behavior, much faster installs.
The core idea:
- Prepare artifacts once in a global cache (
~/.cache/scint). - Materialize into
.bundle/via clonefile/hardlink/copy. - Warm installs are effectively instant because no fetch, extract, or compile happens when the cache is populated.
From scintillation: short, high-energy flashes.
- Event-driven scheduling.
- Burst parallelism where safe.
- Tight phase boundaries with clear handoffs.
Every gem flows through a deterministic cache pipeline. Resolution decides what to install; the pipeline defines how.
flowchart TD
A["Fetch + Assemble"]
B[Compile]
C[Promote]
D[Materialize]
A -->|"gems: download .gem, unpack\ngit: clone, checkout, export"| B
B -->|"native extensions built\ninside assembling tree"| C
C -->|"atomic move to cached/\nwrite .spec.marshal + manifest"| D
D -->|"clonefile / hardlink / copy\nfrom cached/ to .bundle/"| E[Done]
- Fetch + Assemble into
inbound/andassembling/- Download gem payloads to
inbound/gems/. - Clone/fetch git repos into
inbound/gits/<sha256-slug>/. - Unpack
.gemfiles intoassembling/<abi>/<full_name>/. - For git sources: checkout, submodules, then export the tree into
assembling/<abi>/<full_name>/.
- Download gem payloads to
- Compile in
assembling/- Native extension builds happen inside the assembling directory so outputs are part of the final tree.
- Promote atomically to
cached/- Move
assembling/<abi>/<full_name>/tocached/<abi>/<full_name>/. - Write
cached/<abi>/<full_name>.spec.marshaland.manifest. - Failed builds never reach
cached/.
- Move
- Materialize to
.bundle/- Clonefile/reflink/hardlink/copy from
cached/<abi>/. - No rebuild if the cached artifact is valid.
- Clonefile/reflink/hardlink/copy from
One truth source for warm installs: cached/<abi>.
The Scheduler is the install session object. It owns the job graph, worker pool, and phase coordination.
flowchart TD
subgraph "Early Parallel"
FI[fetch_index]
GC[git_clone]
end
FI --> R[resolve]
GC --> R
R --> P[plan]
subgraph "Install DAG"
DL[download] --> EX[extract]
EX --> LN[link]
LN --> BE[build_ext]
BE --> BS[binstub]
LN --> BS
end
P --> DL
P --> LN2["link (cached)"]
LN2 --> BS2[binstub]
Job priorities (lower = dispatched first):
| Priority | Job Type | Concurrency |
|---|---|---|
| 0 | fetch_index |
all workers |
| 1 | git_clone |
all workers |
| 2 | resolve |
1 |
| 3 | download |
bounded (default 8) |
| 4 | extract |
IO-limited |
| 5 | link |
IO-limited |
| 6 | build_ext |
CPU-limited (slots x make -j) |
| 7 | binstub |
1 |
Workers start at 1, scale dynamically up to cpu_count * 2 (max 50). Compile concurrency is tuned separately: a small number of slots each running make -jN to keep CPU saturated without thrashing.
Fail-fast mode aborts scheduling after the first hard failure.
Global cache (~/.cache/scint):
~/.cache/scint/
inbound/
gems/<full_name>.gem
gits/<sha256-slug>/
assembling/
<ruby-abi>/<full_name>/
cached/
<ruby-abi>/
<full_name>/
<full_name>.spec.marshal
<full_name>.manifest
index/
<source-slug>/
ABI key example: ruby-4.0.1-arm64-darwin25
Project-local runtime (.bundle/):
.bundle/
ruby/<major.minor.0>/
gems/ # materialized gem trees
specifications/ # gemspecs
bin/ # gem binstubs
bin/ # project-level wrappers
scint.lock.marshal
Cache root precedence: SCINT_CACHE > XDG_CACHE_HOME/scint > ~/.cache/scint.
A cached artifact is valid when:
cached/<abi>/<full_name>/exists..spec.marshalexists and loads..manifestexists, parses, schema version is supported, and fields match.- If the gem has native extensions, the build-complete marker exists.
Invalid entries are rebuilt through the full pipeline. Legacy entries without manifests are read-compatible but emit telemetry for deprecation tracking.
- If
cached/<abi>/<full_name>/is valid, no fetch/extract/compile occurs. - Deleting
.bundle/triggers only materialization. - Materialization is IO-bound and close to instantaneous on warm cache.
- Incomplete assemblies are never promoted.
scint install # install from Gemfile.lock
scint add <gem> # add to Gemfile and install
scint remove <gem> # remove from Gemfile and install
scint exec <cmd> # run command in bundle context
scint cache list # list cached gems
scint cache clear # clear global cache
scint cache dir # print cache rootOptions: --jobs N, --path P, --verbose, --force.
scint exec sets GEM_HOME/GEM_PATH, injects load paths from scint.lock.marshal, and execs the command. Bundler compatibility: BUNDLE_PATH=".bundle" bundle exec works against the same layout.
# Ruby sampling profile
SCINT_PROFILE=/tmp/profile.json scint install --force
# Ruby IO trace
SCINT_IO_TRACE=/tmp/io.jsonl scint install --force
# Summarize IO trace
scint-io-summary /tmp/io.jsonl
# Syscall trace (strace/dtruss)
scint-syscall-trace /tmp/sys.log -- scint install --forcebin/scint-vs-bundler [--force] /path/to/project
bin/scint-bench-matrix [--force] --root /path/to/projectsscint-bench-matrix runs cold/warm benchmarks for every project subdirectory and writes logs/bench-<timestamp>/summary.tsv and table.md. If <root>/<project>-test.sh exists, it runs as a smoke test after the benchmark.
Experimental. Optimized for architecture iteration speed.