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 with Claude Code
Connect Claude Code 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 Claude to build a counter or debug your ALU — it writes the TypeScript and the circuit appears on your canvas instantly.
See the Claude Code Integration guide for the full 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: