Overview
A digital logic simulator for learning and building hardware designs
Simten is a browser-based platform for learning digital hardware design. You write circuits in TypeScript using the circuit() factory, see them rendered live on an interactive canvas, and simulate them with time-travel debugging. An AI tutor (Claude) can help you build, debug, and understand circuits in real time.
What you can build
Everything runs in the browser — no toolchain, no installation, no FPGA required.
- Logic gates and adders — start from AND, OR, XOR and build up to full adders and ALUs
- Sequential circuits — counters, shift registers, state machines using registers and flip-flops
- Games in hardware — Snake and Pong, built entirely from logic gates with no CPU
- A complete CPU — a 5-stage pipelined RISC-V processor that runs compiled C code
- Accelerators — a TPU systolic array doing matrix multiplication, a CORDIC unit computing trigonometry
- Networking hardware — an Ethernet switch with frame parsing, buffering, and forwarding
Hardware & FPGA
Circuits that export to Verilog can go all the way to a physical FPGA bitstream. The Hardware & FPGA page covers the full pipeline — Yosys synthesis, nextpnr place-and-route, ecppack, and flashing — using Snake running on a ULX3S ECP5 board over HDMI as a worked example.
Verilog export
Circuits export to synthesizable Verilog. The exporter maps 60+ primitives to standard RTL constructs — assign for combinational logic, always @(posedge clk) with synchronous active-low reset (rst_n) for sequential logic. Every module containing sequential primitives gets input clk and input rst_n ports auto-emitted (no clock or reset wiring in your circuit() definitions); on rst_n low, registers snap to their value arg, memories preserve contents, RV32I register files zero. The output is verified against Icarus Verilog via a containerized verification service.
import { exportVerilog } from '@simten/core/verilog';
const { verilog, files } = exportVerilog(circuit, library, { target: 'synthesis' });
// `verilog` is the .v source; `files` is a map of sidecar filename → contents
// (hex files referenced by $readmemh for large preloaded memories).The target: 'synthesis' option strips simulation-only constructs (initial blocks) for FPGA-ready output. Memories above inlineMemoryThreshold (default 2048 words) are emitted as $readmemh("<file>.hex", reg) with the hex contents returned alongside — matching the Yosys/Vivado/Quartus convention for large ROM/RAM initialization.
AI tutor over MCP
Connect an MCP-capable assistant — Claude Code, Codex CLI, Gemini CLI, Cursor, and others — to get an AI tutor that can see your circuit, push changes to the browser, run simulations, and answer questions in real time:
claude mcp add simten npx @simten/mcpAsk it to build a counter or debug your ALU — it writes the TypeScript and the circuit appears on your canvas instantly.
See the MCP Integration guide for per-client setup, available tools, and how the MCP viewer works.
Circuit code runs in an isolated sandbox — see Security Architecture for how Simten protects your credentials and filesystem from untrusted circuits.
Packages
@simten/core ← headless engine (no UI)
↑
@simten/ui ← visual components (nodes, canvas, editor)
↑
@simten/embed ← batteries-included wrapper + web components| Package | Description |
|---|---|
@simten/core | TypeScript builder, compiler, validator, simulator engine, SimulationSession, Verilog export |
@simten/ui | Canonical node components, shared canvas, ELK layout, sandbox context, ClockControls |
@simten/embed | CircuitEmbed convenience wrapper, useCircuitSimulator hook |
@simten/mcp | MCP server for Claude Code integration |
Embed a circuit
Drop an interactive circuit into any React app:
import { CircuitEmbed } from '@simten/embed';
import { circuit, bit } from '@simten/core/circuit';
import { Xor, And } from '@simten/core/std';
const HalfAdder = circuit('HalfAdder', {
inputs: { a: bit, b: bit },
outputs: { sum: bit, carry: bit },
nodes: { xor1: Xor, and1: And },
connect: ({ inputs, outputs, nodes: { xor1, and1 } }) => [
inputs.a.to(xor1.a, and1.a),
inputs.b.to(xor1.b, and1.b),
xor1.out.to(outputs.sum),
and1.out.to(outputs.carry),
],
});
<CircuitEmbed circuit={HalfAdder} height={250} showControls />The embed auto-wraps the circuit with switches for inputs and LEDs for outputs.
Here's that exact code running live: