
Hello everyone, I’m Harkeerat Singh (Harkeerat24) and this is my mid-term blog post for Google Summer of Code 2026 with CircuitVerse for the project Structured Format for Saved Circuit Data.
Here’s the problem the project set out to fix: two logically identical circuits, saved in a different order, had been producing completely different save files. Because there was no canonical representation, identical circuits did not hash the same, could not be reliably diffed, and could not be trusted for features that depend on stable output.
The goal of this project is to design and implement a canonical JSON format that produces identical output for any two logically equivalent circuits, in the Vue-based simulator (cv-frontend-vue).
The Community Bonding period kicked off on May 2nd, 2026 with a meeting where GSoC contributors, mentors, and maintainers met. The atmosphere was incredibly warm, relaxed, and welcoming. It was more like a friendly hangout than a formal call.
On May 9th, 2026, I had my project kickoff meeting with my mentors (Aboobacker, JoshVarga, Arnabdaz, and Aryann). We went through the project timeline, discussed our serialization algorithm design in depth, and aligned on how the canonical format should handle complex edge cases. It was a fun, highly insightful session that left me with a clear direction for the weeks ahead.
During this period, I worked on closing a few issues in cv-frontend-vue that may come in handy later in the project. Here are the merged PRs from that work:
==) with strict equality (===) in the circuit selection logic to fix incorrect matches caused by type coercion.The first week was dedicated to implementing the core export pipeline and canonicalization logic in canonical.ts.
The core of the canonicalization pipeline utilizes the 1-Dimensional Weisfeiler-Leman (1-WL) graph algorithm to generate a structural fingerprint for each component. This ensures that component sorting is independent of the sequence in which components were originally placed or saved.
Once the single-circuit case was stable, the focus shifted to extending the canonical format to support multi-circuit projects. While basic multi-circuit serialization came together smoothly, the more challenging aspect, which is subcircuit dependency ordering, was deferred to the following week.
This week was dedicated to solving the subcircuit dependency challenge: if Circuit B uses Circuit A as a subcircuit, Circuit A must be processed before Circuit B to guarantee determinism.
Two key mechanisms made this possible:

By the end of this week,
canonical.tswas capable of generating deterministic canonical JSON for any valid layout — single circuit, multi-circuit, or nested subcircuits.
This sprint was slower than planned — I was unwell for a good part of it. Even so, I managed to draft most of importCanonical.ts, the file responsible for reconstructing the circuit on the canvas from the canonical JSON generated by canonical.ts. The planned JSON Schema validation work got pushed to the next sprint.
During Sprint 5, I completed the implementation of importCanonical.ts. The import pipeline handles:

My mentors went through the existing PRs I’d raised, caught a couple of issues, and floated a great optimization idea along the way: caching canonical hashes so unmodified circuits can skip the full pipeline on save. That’s now planned for the second half. I worked through their feedback, resolved the open PR conversations, and got PR #1095 merged!
With that foundation in place, my focus shifted to hooking the engine up to the real cv-frontend-vue frontend.
On the import side, I updated the workflow to accept the new deterministic canonical structure and dropped support for the legacy layout parsing. I also added a backup — if a canvas import crashes or fails for any reason, the system automatically rolls back and preserves the user’s existing work instead of wiping the canvas.
On the export side, I tied the “Export as File” action directly to canonical.ts so it outputs clean .cv files. To make the feature more developer-friendly, I added:

This video showcases all the progress made during the first phase of the project:
| PR | Title | Status |
|---|---|---|
| #1093 | gsoc26: Implementing canonical pipeline for deterministic json | Closed — superseded by #1095 |
| #1094 | gsoc26: multi circuit support in canonical.ts | Closed — superseded by #1095 |
| #1095 | feat: added subcircuit support in canonical.ts using khans algorithm | Merged |
| #1131 | feat: add canonical JSON import pipeline with round-trip verification | Merged |
| #1132 | feat: update Export Project dialog and import project for canonical support | Merged |
| — | JSON Schema and validation | In Progress |
| — | Writing tests | In Progress |
Note: The current pull requests are raised in the
v1of the repository. This lets us test the canonicalization and import pipelines thoroughly without any risk of breaking the main simulator workflow.
.ts directly from the beginning was a great decision. The compile-time type safety it introduced made refactoring complex serialization logic much safer and is overall much better for the project’s long-term maintenance.unknown with strict typings forced us to define the format’s actual shape, catching bugs at compile-time.canonicalSchema.json and integrate validation into importCanonical.ts.ELK.js library to automatically generate readable layouts for circuits imported without positioning format..cv files into the new format.I’m incredibly grateful to my mentors Aboobacker, JoshVarga, Arnabdaz, and Aryann for their guidance, feedback, and support throughout the first half of the project. I also want to thank the CircuitVerse community for their warm welcome and collaborative environment.
I’m looking forward to a productive and exciting second half of GSoC!