Evaluate code in a full tscircuit runtime environment, including babel
transpilation and execution, so you just need to send the code to be executed
with automatic handling of imports from @tsci/*
The circuit
object from @tscircuit/core
is already exposed on the global
scope. All imports from @tsci/*
are automatically handled.
import { createCircuitWebWorker } from "@tscircuit/eval-webworker"
const circuitWebWorker = createCircuitWebWorker()
await circuitWebWorker.execute(`
import { RedLed } from "@tsci/seveibar.red-led"
circuit.add(
<board width="10mm" height="10mm">
<RedLed />
</board>
)
`)
await circuitWebWorker.renderUntilSettled()
const circuitJson = await circuitWebWorker.getCircuitJson()
For simple cases where you don't need web worker isolation, you can use CircuitRunner directly in the main thread:
import { CircuitRunner } from "@tscircuit/eval-webworker"
const circuitRunner = new CircuitRunner()
await circuitRunner.execute(`
import { RedLed } from "@tsci/seveibar.red-led"
circuit.add(
<board width="10mm" height="10mm">
<RedLed name="LED1" />
</board>
)`)
await circuitRunner.renderUntilSettled()
const circuitJson = await circuitRunner.getCircuitJson()
// Validate circuit elements
const led = circuitJson.find((el) => el.name === "LED1")
You can also execute code using a virtual filesystem, which is useful when you have multiple files or components:
import { createCircuitWebWorker } from "@tscircuit/eval-webworker"
const circuitWebWorker = createCircuitWebWorker()
await circuitWebWorker.executeWithFsMap({
fsMap: {
"entrypoint.tsx": `
import { MyLed } from "./myled.tsx"
circuit.add(
<board width="10mm" height="10mm">
<MyLed name="LED1" />
</board>
)
`,
"myled.tsx": `
import { RedLed } from "@tsci/seveibar.red-led"
export const MyLed = ({ name }) => {
return <RedLed name={name} />
}
`,
},
entrypoint: "entrypoint.tsx",
})
await circuitWebWorker.renderUntilSettled()
const circuitJson = await circuitWebWorker.getCircuitJson()
CircuitRunner (Direct Execution)
- ✅ Simple debugging
- ✅ No worker setup required
- ❌ Blocks main thread
- ❌ No isolation from host environment
CircuitWebWorker (Web Worker)
- ✅ Non-blocking execution
- ✅ Isolated environment
- ✅ Better for production use
- ❌ More complex setup
- ❌ Comlink overhead for communication
tscircuit can block the ui thread in a browser. In addition, tscircuit sometimes freezes during the render loop due to autorouting or other computationally intensive operations. Executing tscircuit code in a web worker allows the ui to display the rendering process without freezing, and stop rendering if it goes on for too long.
- The execution code is scanned for imports, these imports are then loaded via fetch from the CDN and added to a global import map.
- The code is transpiled. Imports/requires automatically check the import map.
- The transpiled code is executed with a
circuit
object added to the global scope. - When a user calls
circuitWebWorker.renderUntilSettled()
, the web worker the webworker runscircuit.renderUntilSettled()