Camofleur — PGA Layout Designer
A custom Pin Grid Array layout designer built for actual hardware layout work.
There are no templates or predefined pin types — you have to define everything yourself (which is kind of the point).
Why I made this (and where it went wrong first)
This started while I was trying to design a 132-pin Harvard architecture CPU socket for something I call Project Neumann.
The initial idea was honestly simple: just use a browser-based simulator to visualize the layout.
That… did not go well.
I tried rendering a 38×38 grid of circular pins (which is 1,444 SVG elements), while also tracking around 13 different arrays for specific pin groups. The browser basically gave up — the sandbox server timed out and crashed.
It felt like the system was saying:
“this is not what I’m built for”
I think I just pushed it too far.
So instead of fighting that, I switched approaches and started building a small tool for myself:
use canvas instead of SVG store everything in one flat grid instead of multiple arrays keep it fast enough to drag across a lot of pins without freezing
That eventually became Camofleur.
What I was actually trying to design
The tool mostly exists because of this layout, so this part probably explains the decisions better.
Imagine a 10×10 cm board. The 132 pins sit in a double-thick square around the edges, leaving the center empty (mostly for airflow and routing space).
Everything is placed so wires don’t cross, at least in theory.
Corners — power Top-left and bottom-right: VCC 5V (3 pins each → 6 total) Top-right and bottom-left: GND (3 pins each → 6 total) North edge — RAM data Outer row: D0–D7 (8 pins) Inner row: D8–D15 (8 pins) South edge — RAM address Outer row: A0–A7 (8 pins) Inner row: A8–A15 (8 pins) East edge — ROM data Outer row: 0–7 (8 pins) Inner row: 8–15 (8 pins) West edge — ROM address + program counter Outer row: A0–A7 (8 pins) Inner row: A8–A15 (8 pins) Inner expansion zones GPU bus (20 pins): placed near RAM since it needs memory access Peripheral I/O (16 pins): near the north edge Control + IPC (20 pins): placed near the program counter
Total: 132 pins.
I tried to keep routing clean and avoid crossings, though I’m not 100% sure it’s optimal.
What Camofleur does Draws a fully custom X×Y grid of circular pins using HTML5 canvas (default 38×38, can go up to 200×200) Starts completely empty — no predefined categories Lets you define your own pin types: name color optional limit (0 = no limit) Paint pins by clicking or dragging Tracks counts live and stops you if you exceed limits Uses a PGA-style coordinate system: rows: A, B, C… (skips I, O, Q, S, X, Z) columns: numbered from 1 Hover to see labels (like A3, B12) Undo / redo (Ctrl+Z / Ctrl+Y) Export: PNG with legend JSON (save/load layouts) CSV (pin table) Clear board (with confirmation, because I accidentally wiped things a few times) Why canvas instead of SVG (what I understood at least)
SVG started becoming a problem once the grid got large.
Each pin is its own element, which means:
lots of DOM nodes event listeners per pin constant re-rendering
Canvas is simpler in that sense — everything is drawn in one pass.
The grid is just a flat array:
index = row * width + col
So instead of updating many elements, it just redraws the whole thing.
It’s not fancy, but it works much better for this use case.
Tech stack Next.js 15 (App Router) React 19 Tailwind CSS HTML5 Canvas API Running locally npm install npm run dev
Open: http://localhost:4028/pga-layout-designer
Scripts npm run dev — start dev server (port 4028) npm run build — production build npm run lint — ESLint npm run format — Prettier npm run type-check — TypeScript check