GDSJam is a GDSII and DXF file viewer available as both a web application and desktop app. Built for academics, chip design newcomers, and the photonics community to promote open-source EDA culture.
Web Version: Client-side processing in the browser - your files never leave your device.
Desktop App: Native application with file watching and auto-reload capabilities for local development workflows.
- GDSII/DXF viewing with WebGL acceleration
- LOD rendering with polygon budgeting for large files
- Layer visibility controls with sync option
- P2P collaboration via WebRTC + Y.js (shareable sessions, host/viewer model, viewport sync)
- Interactive minimap showing all participants' viewports
- Mobile-friendly with touch controls
- Desktop app with file watching and auto-reload (macOS, Windows, Linux)
- Frontend: Svelte 5 + TypeScript + Vite
- Rendering: Pixi.js v8 (WebGL2)
- GDSII Parsing: gdsii by TinyTapeout
- Spatial Indexing: rbush (R-tree for viewport culling)
- Desktop: Tauri v2 (Rust + system WebView)
- Styling: Tailwind CSS v4
- Tooling: Biome, Vitest, Husky
# Install dependencies
pnpm install
# Start dev server
pnpm dev
# Run type checking
pnpm check
# Run linter
pnpm lint
# Run tests
pnpm testGDSJam can be embedded into any webpage as an interactive, zoomable “image-like” viewer.
- Use
?embed=trueto enable embed mode (viewer-only UI) - Use
?url=<GDS_URL>to load a remote GDS file
Example:
<iframe
src="https://gdsjam.com/?embed=true&url=https://example.com/chip.gds"
width="800"
height="600"
style="border: 1px solid #333; border-radius: 8px;"
></iframe>If you use ?url=..., the remote server hosting the .gds/.gdsii must allow cross-origin fetches.
If it doesn’t, the embed will fail with a CORS/network error.
Embedding is controlled by HTTP response headers from your hosting/CDN:
- Do not send
X-Frame-Options: DENYorX-Frame-Options: SAMEORIGIN - If you use CSP, ensure
Content-Security-Policydoes not include a restrictiveframe-ancestorsdirective (or set it to allow your embedding sites)
When embedded, the iframe listens for messages from the parent page:
- Load file:
{ type: "gdsjam:loadFile", url: "https://example.com/chip.gds" } - Get state:
{ type: "gdsjam:getState" }
The iframe sends messages to the parent:
{ type: "gdsjam:ready" }{ type: "gdsjam:fileLoaded", url, fileName? }{ type: "gdsjam:error", message }{ type: "gdsjam:state", state }
Example parent code:
<iframe id="gds" src="https://gdsjam.com/?embed=true" width="800" height="600"></iframe>
<script>
const iframe = document.getElementById("gds");
window.addEventListener("message", (ev) => {
if (!ev.data || !ev.data.type) return;
console.log("from iframe:", ev.data);
});
iframe.addEventListener("load", () => {
iframe.contentWindow.postMessage(
{ type: "gdsjam:loadFile", url: "https://example.com/chip.gds" },
"*",
);
});
</script>Prerequisites:
- Rust (for Tauri backend)
- All web dependencies (pnpm install)
# Run desktop app in development mode (with hot reload)
pnpm tauri:dev
# Build production desktop app
pnpm tauri:buildDesktop Features:
- Native file picker with GDS/DXF filters
- File watching with auto-reload (500ms debounce)
- Path persistence across app restarts
- All web features included
See src-tauri/README.md for detailed desktop app documentation.
- Coordinate System: Database units with Y-up Cartesian convention (typically µm, but depends on file)
- Rendering: LOD with polygon budgeting, R-tree spatial indexing for viewport culling
- Collaboration: Y.js CRDT with WebRTC, host as ground truth (localStorage), viewers sync via signaling server
This project uses the following open-source libraries:
- gdsii - GDSII parser by TinyTapeout (MIT/Apache-2.0)
- Pixi.js - WebGL rendering engine (MIT)
- rbush - High-performance R-tree spatial index by Vladimir Agafonkin (MIT)
- Svelte - Reactive UI framework (MIT)
Without collaboration sessions: This webapp is entirely client-side — all file processing happens in your browser and your files never leave your device.
With collaboration sessions: When you host or join a session:
- Files you upload are temporarily stored on our server for sharing with session participants
- Files are stored as content-addressed blobs (SHA-256 hash) and automatically deleted after 7 days
- We log IP addresses for rate limiting (max 10 uploads/hour) and security purposes
- No user accounts are created — we don't track personal information beyond what's technically necessary
- Session metadata (file name, size, uploader ID) is synchronized via WebRTC to session participants
Recommendation: Do not upload files containing sensitive or proprietary designs if you're not comfortable with temporary server-side storage.
MIT
Created by Wentao and Claude.


