Runs in your browser. No toolchain to install.
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, 1fast-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) });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>
);
}An MCP server lets Claude, Codex, Gemini, or Cursor write, simulate, and debug circuits live in your browser: describe, generate, fix, ship.
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.
Compiling Rust to RISC-V…
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 {Every composite is explorable. Double-click the pulsing badge to open its internals, with full simulation and nested drill-down.
Sequential circuits record every state. Step forward, spot something wrong, step back to the exact cycle it happened. No printf debugging, just rewind.
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.
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),
],
});`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