tscircuit is at patch 2744 and has never cut a release
Project brief: Create real electronics with Typescript and React. Think of tscircuit as "React for Electronics" It allows you to design real-world electronic circuits using Typescript and React.
At a glance
- What is it?
- tscircuit renders circuit boards from React components written in TypeScript, and exports Gerbers, a pick and place file and a bill of materials. Its root package sits at version 0.0.2744, the repository has no GitHub releases at all, and the publishing story is four separately pinned sub-projects plus a build that runs on bun.
- Who is it for?
- tscircuit is worth a try if you already design in React and want a schematic in the browser this afternoon, and it is a poor fit if you need a stable component library, because there is no release train to pin against and the root package sits four digits into a patch series.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four digits into a patch series, and no tag to pin
The root package.json reads version 0.0.2744, and the repository has no GitHub releases behind it. So there is nothing to pin a dependency to, no changelog attached to a tag, and no artifact to roll back to. What fills the gap is the upgrade-deps script, which is where the real dependency policy lives. It runs a single update command against four packages at once, @tscircuit/core, @tscircuit/cli, @tscircuit/eval and @tscircuit/runframe, then copies core versions into place and reinstalls with install scripts disabled. Four moving parts advance independently of the root number, which means the root version tells you almost nothing about what is inside a given install. The same script is the answer to how the sub-projects keep in step, and it is a script rather than a policy document: no cadence, no compatibility matrix, and no statement about which of those four a given feature depends on.
The exports map gives the browser entry no types
The published surface is small enough to read in full, and one of its three declarations is missing something. The exports map has a root entry carrying a types condition pointing at dist/index.d.ts and a default condition pointing at dist/index.js, plus a single subpath, ./browser, mapped straight to dist/browser.min.js with no types condition attached at all. A TypeScript consumer importing that subpath gets JavaScript and no declarations to check against. The files array ships exactly three things, dist, cli.mjs and globals.d.ts, which also means the docs, tests, scripts and types directories visible in the repository never reach an installed copy. The bin field then maps two command names onto one file, tsci and tscircuit both pointing at cli.mjs, so the short tool everyone is told to run and the package name itself are the same program reached by two aliases.
The build runs on bun while the front door is npm
The install line on the page is npm install -g tscircuit, followed by tsci dev, and the browser opens at localhost:3020. The build that produces the package is a different toolchain entirely.
"build": "tsup-node && bun run copy-runframe-standalone && bun run copy-eval-webworker && cp types/static-assets.d.ts dist/static-assets.d.ts && bun run add-global-types-reference",
"add-global-types-reference": "echo '/// <reference path=\"../globals.d.ts\" />' | cat - dist/index.d.ts > dist/index.d.ts.tmp && mv dist/index.d.ts.tmp dist/index.d.ts",
"test": "bun test",Five chained steps: a tsup bundling call, two copies driven by bun, one plain cp of a declaration file, and a step that rewrites dist/index.d.ts in place by concatenating a reference to globals.d.ts onto it through a temporary file. The lockfile is bun.lock and the test command is the built-in bun runner. So consumers arrive through npm while the project itself builds and tests on bun, and that final step depends on a POSIX shell and cp rather than on anything the package manager provides. An ava.config.js sits in the repository root configuring a different runner that the test script never invokes.
Every box in the feature list is already ticked
The more-features block is a markdown task list in which all eight items are pre-checked: previewing PCBs and schematics in the browser, using normal TypeScript and React tooling, exporting Gerbers, Pick'n'Place and a BOM, adding registry packages with tsci add, publishing subpackages with tsci push, simplified extensible auto-routing, importing footprints from third-party sites, and generating footprints from text using AI. Because the source has them checked, the list carries no status information at all. The clearest case is auto-routing, which is marked done while the FAQ entry titled Is the auto-routing good? answers only that work is under way towards a state-of-the-art web based autorouting algorithm and links a progress blog. The opening line makes a similar claim with a multiplier, telling you to prompt your agent to use tscircuit and 10x its PCB capabilities, with nothing on the page measuring what that means. Two URLs for one feature drift apart as well: the header links a playground path and the FAQ answers the browser question with an editor path.
The FAQ writes pcbX and the example writes pcb_x
The single circuit example on the page is twenty lines and teaches two things at once, one of them by accident.
const Circuit = () => (
<board width="50mm" height="50mm" center_x={0} center_y={0}>
<MySubcomponent name="U1" center={[0, 0]} footprint="sot236" />
<resistor
x={2}
y={-0.5}
name="R1"
resistance="10ohm"
footprint="0805"
pcb_x="4mm"
pcb_y="-1mm"
/>
<ground x={3} y={1} name="GND" />
<trace path={[\".U1 > .D0\", \".R1 > .left\"]} />
<trace path={[\".R1 > .right\", \".GND > .gnd\"]} />
</board>
)The resistor carries two coordinate pairs, x and y for one space and pcb_x and pcb_y for another, and the ground and the subcomponent use x, y and center instead. The FAQ on placement says you should currently specify pcbX and pcbY, in a different casing from the example. The snippet is also not self-contained: MySubcomponent is never defined and there are no imports, yet the traces select pins on it through a selector syntax, dot prefixed names joined by a greater than sign, reaching .U1 > .D0 and .GND > .gnd. The ESP32 Wifi Breakout Board above it is a link to a hosted demo, so the chip in that title appears nowhere in the code that follows.
Lowercase tags are why globals.d.ts has to be spliced in
This is the whole of the second code example, the one that answers how the library works inside somebody else's app.
import { Schematic } from "@tscircuit/schematic-viewer"
export const MyApp = () => (
<div>Regular web react here!</div>
<Schematic>
<resistor name="R1" resistance="10k" />
</Schematic>
)Schematic is a capitalised component imported from a separate package, while resistor is lower case and carries no import, which is only legal because something declared it as a JSX intrinsic element. That declaration is what globals.d.ts holds, and it is why the build has to append a reference to it onto the generated dist/index.d.ts, and why globals.d.ts is one of only three entries in the files array. The cost of this design shows up in the exports map instead of in the component list: the browser build is shipped as a prebuilt minified file with no accompanying declarations, and the type surface a TypeScript user relies on reaches them through a global augmentation rather than through an exported namespace.
Rollup plugins and a rasteriser sit in the runtime dependency list
The dependencies of a library that renders circuits include the plugins a bundler needs. Alongside @flatten-js/core, a geometry library, and @lume/kiwi, a serialization format, the list carries @resvg/resvg-js for rasterising SVG, and then @rollup/plugin-commonjs, @rollup/plugin-json and @rollup/plugin-node-resolve, with a fourth Rollup entry starting @rollup/plugin-ty before the listing stops. Three separate Rollup plugins and a native rasteriser are ordinary dependencies of whatever installs this package, not optional extras, which is a heavier tree than the React for Electronics framing suggests and a plausible source of trouble in a browser bundler that already owns those roles. devDependencies are much lighter by comparison, four entries, @types/bun, esbuild, esbuild-register and tsup, with TypeScript held as a peer dependency at ^5.0.0 rather than installed for you. The dependency list is also the place where the page stops mid key, so the remaining runtime requirements are not readable here at all.
Editorial conclusion
tscircuit is worth a try if you already design in React and want a schematic in the browser this afternoon, and it is a poor fit if you need a stable component library, because there is no release train to pin against and the root package sits four digits into a patch series. Before building anything real, read the exports map rather than the README: the browser entry ships no type declarations, and the lowercase circuit tags only typecheck because globals.d.ts is injected into the published index.d.ts. Confirm the autorouting claim yourself, since the feature list and the FAQ disagree about whether it is finished.
Frequently asked questions
Can I design my own PCB?
That is what the project is for: instead of creating a web element like div, you create circuit elements like chip, resistor or capacitor, and the result renders as a 3d circuit you can order. The documented entry is npm install -g tscircuit followed by tsci dev, which opens a browser at http://localhost:3020, and the page states you can export Gerbers, Pick'n'Place and a BOM for manufacturing.
Is tscircuit free to use?
The FAQ entry answers that tscircuit is completely free and MIT-licensed open source, and the root package.json carries license MIT. That sentence covers the package. The registry, the tsci push publishing flow for subpackages, and the hosted text to footprint tool are named separately on the same page and are not part of it.
Does tscircuit have GitHub releases I can install from?
The repository has none. The root package.json is at version 0.0.2744, and the upgrade-deps script is what moves the rest of the stack, running bun update --latest against @tscircuit/core, @tscircuit/cli, @tscircuit/eval and @tscircuit/runframe before copying core versions and reinstalling with install scripts disabled.
Does tscircuit place components on the board for me?
Not yet. The FAQ says you should currently specify pcbX and pcbY and nest inside group elements for convenience, and that work is under way on autolayout algorithms described as the equivalent of flex and CSS Grid, where automatic placement will be overridable. The circuit example on the same page uses the snake_case pcb_x and pcb_y instead of that casing.
How good is the tscircuit auto-router?
The page does not say. The feature list marks simplified, extensible auto-routing for PCBs as done, while the FAQ entry titled Is the auto-routing good? answers only that the project is working towards a state-of-the-art web based autorouting algorithm and sends you to autorouting.com for progress.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tscircuit-tscircuit)