80 karma · joined October 21, 2015
— Memory limits: JS_SetMemoryLimit per-runtime (256 MB default), JS_SetContextMemoryLimit per-context. Exceeding → JS exception, not a crash.
— Execution limits: interrupt handler checks a nanosecond deadline every opcode. For contexts, max_reductions caps JS operations independently of wall-clock time.
— API surface: apis: false gives bare QuickJS — no fetch, no fs, no DOM, no I/O. You control exactly which Elixir functions JS can call via the handlers map. JS cannot call arbitrary Elixir code.
— Conversion limits: max_convert_depth (32) and max_convert_nodes (10k) prevent pathological objects from blowing up during JS↔BEAM conversion.
— Process isolation: separate OS thread, separate QuickJS heap per runtime.
No seccomp — QuickJS runs in-process so seccomp would restrict the entire BEAM. The sandbox boundary is QuickJS-NG's memory-safe interpreter (no JIT, no raw pointer access from JS) plus the API surface control above.
2. No. JS runs on a dedicated OS thread, outside the BEAM scheduler. But there's an interrupt handler (JS_SetInterruptHandler) that checks a deadline on every JS opcode boundary — pass timeout: 1000 to eval and it interrupts after 1s, runtime stays usable. For contexts there's also max_reductions — QuickJS-NG counts JS operations and interrupts when the budget runs out, closest analog to BEAM reductions.
3. QuickJS-NG uses refcounting with cycle detection. Each runtime/context has its own GC — one collecting doesn't touch another. When a Runtime GenServer terminates, JS_FreeContext + JS_FreeRuntime release everything.
4. No, standard JS mutability. But the JS↔Erlang boundary copies values — no shared mutable state across that boundary.
5. QuickJS-NG enforces JS_SetMemoryLimit per-runtime (default 256 MB) and JS_SetContextMemoryLimit per-context. Exceeding the limit raises a JS exception, not a segfault. It propagates as {:error, ...} to the caller. Since each runtime is a supervised GenServer, the supervisor restarts it. There are tests for OOM in one context not crashing the pool, and one runtime crashing not affecting siblings.
# Read path data
figma-use path get <id>
# Set new path
figma-use path set <id> "M10,10 L90,50 L10,90 Z"
# Transform existing paths
figma-use path move <id> --dx 100 --dy 50
figma-use path scale <id> --factor 2
figma-use path flip <id> --axis x
SKILL.md updated too figma-use variable create "brand/primary" --collection <id> --type COLOR --value "#3B82F6"
Then reference them in JSX render: figma-use render ./Button.figma.tsx
const colors = defineVars({
primary: { name: 'brand/primary', value: '#3B82F6' },
})
export default () => (
<Frame style={{ backgroundColor: colors.primary }}>
<Text style={{ color: '#FFF' }}>Button</Text>
</Frame>
)
So if you map your design tokens to Figma variables first, components will reference them. Parsing CSS/Tailwind configs automatically could be a good feature though.Personally, I’d really like to automate part of the workflow around exporting from Figma and assembling a design system into components — right now there’s just too much manual work involved.