Works with Claude + MCP
Write hardware in TypeScript. Test it with npm. Run it on an FPGA.
Runs in your browser. No toolchain to install.
Type-safe end to end
Circuits are TypeScript. Runs natively in Node, Bun, or browser: no testbench language, no codegen step.
import { circuit, bit } from '@simten/core';
import { Xor, And, Or } from '@simten/core/std';
import { simulate } from '@simten/core/sim';
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),
],
});
const FullAdder = circuit('FullAdder', {
inputs: { a: bit, b: bit, cin: bit },
outputs: { sum: bit, cout: bit },
nodes: { ha1: HalfAdder, ha2: HalfAdder, or1: Or },
connect: ({ inputs, outputs, nodes: { ha1, ha2, or1 } }) => [
inputs.a.to(ha1.a),
inputs.b.to(ha1.b),
ha1.sum.to(ha2.a),
inputs.cin.to(ha2.b),
ha2.sum.to(outputs.sum),
ha1.carry.to(or1.a),
ha2.carry.to(or1.b),
or1.out.to(outputs.cout),
],
});
// Same engine in Node: no codegen, no testbench.
const sim = simulate(FullAdder);
sim.set({ a: 1, b: 1, cin: 1 });
console.log(sim.get('sum'), sim.get('cout')); // 1, 1Bring any npm package
fast-check for property testing, D3 for visualization, the GCC RISC-V toolchain. Your circuit code is just code.
// figlet: ASCII art baked into a hardware ROM
import figlet from 'figlet';
import smallFont from 'figlet/fonts/Small';
import { ROM, romFromBytes } from '@simten/core/std';
figlet.parseFont('Small', smallFont);
const banner = figlet.textSync('Simten', { font: 'Small' });
const bytes = [...banner].map(c => c.charCodeAt(0));
const Logo = ROM({ memory: romFromBytes(bytes) });Drop-in embeds
One component renders a fully interactive circuit anywhere: blogs, docs, MDX. Same engine as the editor.
import { CircuitEmbed } from '@simten/embed';
import { HalfAdder } from './half-adder';
// Live, interactive hardware in three lines.
export default function Post() {
return (
<article>
<p>Here's a half adder you can poke at:</p>
<CircuitEmbed circuit={HalfAdder} />
</article>
);
}Wire it to your assistant
An MCP server lets Claude, Codex, Gemini, or Cursor write, simulate, and debug circuits live in your browser: describe, generate, fix, ship.
$ claude mcp add simten npx @simten/mcp
✓ added simten
>Build me a 2-bit counter with a reset.
>write_circuit (simten)
5 nodes, 9 connections, 0 errors
>simulate_circuit (simten)
simulation ready · counts 00 → 01 → 10 → 11
Your counter is live. Click Tick to advance.
No CPU. No code. Just gates.
Scale to real-world complexity
The framework already runs heavy systems in the browser: for example, a 5-stage pipelined RISC-V CPU executing GCC-compiled C, C++, and Rust.
Pipeline
Compiling Rust to RISC-V…
Pipeline
IFIDEXMEMWB
Compiling Rust to RISC-V…
// Bare-metal Rust: no OS, no stdlib.
// This runs directly on the CPU hardware.
// When done, register a0 = 55 (0x00000037).
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_: &PanicInfo) -> ! { loop {} }
#[no_mangle]
pub extern "C" fn main() -> i32 {
let mut a: i32 = 0;
let mut b: i32 = 1;
for _ in 0..10 {Disassembly
Compiling to RISC-V…
Drill-down
Explore inside any component
Every composite is explorable. Double-click the pulsing badge to open its internals, with full simulation and nested drill-down.
1.Double-click fa (FullAdder) to see its two HalfAdders
2.Double-click a HalfAdder to see its XOR + AND gates
3.Toggle switches: signals propagate through every level
Time-travel
Rewind any clock cycle
Sequential circuits record every state. Step forward, spot something wrong, step back to the exact cycle it happened. No printf debugging, just rewind.
1.Toggle the switch on, then Tick a few times
2.Watch the bit ripple through the four flip-flop stages
3.Use ◀ ▶ to scrub back and forth; every cycle is preserved
Export to Verilog
Synthesizable primitives export to structural Verilog. The RV32I CPU and Snake both run on a real ULX3S FPGA, with the CPU cross-validated against Icarus Verilog cycle-by-cycle.
circuit.ts
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),
],
});HalfAdder.v✓ verified against Icarus Verilog
`timescale 1ns / 1ps module HalfAdder ( input a, input b, output sum, output carry ); wire w_xor1_out; wire w_and1_out; assign w_xor1_out = a ^ b; assign w_and1_out = a & b; assign sum = w_xor1_out; assign carry = w_and1_out; endmodule