
Hey Everyone ๐,
Welcome to my final blog for Google Summer of Code 2025 for the project Desktop Application & Vue Frontend Updates. At the begining of each heading you can see Deliverable, which gives information for users to know about the feature with no dev-terms(or very less at best ๐). For the dev side, read on!
Desktop Application & Vue Frontend Updates: The project works on the Vue Simulator and aims at completing the vue-simulator. We have achieved several milestones like Authentication model, a beautiful Release Pipeline for Tauri simulator, version sync for v0 and v1, a brand new Testbench UI and best of all pushed vue-simulator to production. Letโs dive into them right away !!
Deliverable: We have finally pushed the vue-simulator to production ๐. We faced a lot of tricky problems along the way but finally after 4 GSoC projects we are here with vue-simulator in Production. The users can use legacy simulator by just clicking on the simulator at the homepage (URL - https://circuitverse.org/simulator). For using vue simulator they need to change the URL to https://circuitverse.org/simulatorvur which is equivalent to https://circuitverse.org/simulatorvue?simver=v0. This sets the v0 (base) version for vue-simulator. Users can also change the URL to https://circuitverse.org/simulatorvue?simver=v1, this sets the version to v1. We will be using v1 to rollout the beta updates for new features ๐งช, after thorough testing and positive user response ๐ weโll move those updates to v0. Users can freely choose to work on either of the three versions: legacy, v0, v1. The working of the Embed view can be seen in the video attached below. ๐ฅ
Letโs tape the tale ๐: Pushing the vue-simulator to production has been the biggest objective for this project. The vision of vue-simulator being giving users option to use the various versions at will gave rise to a lot of contingencies โก. Letโs start with the first major bug ๐ we faced:
When a user saves a circuit it can be viewed in the Dashboard ๐. When going into the Embed view i.e. when we click on more under a circuit we are directed to another page where we see the Embed view. The issue was that the paths were only handled properly for the legacy simulator causing the whole vue-simulator being loaded in the Embed area instead of just a lighter version of the simulator like how it is meant to be for the embedded format. To fix this we had to really delve into the codebase ๐ ๏ธ. Here on is the crux of the situation and how we tackled it.
simulatorVersion was not stored as a separate column in the database ๐๏ธ.simulatorVersion defined at all, since they were created using the legacy simulator ๐ฐ๏ธ.Step 1: Extract the simulator version from project data ๐
We added logic in the Project model to safely read simulatorVersion from the JSON field.
"legacy".This gave us a consistent way to determine whether a project was created with the new Vue simulator or the old legacy one.
Step 2: Add a helper method to detect Vue simulator projects ๐
In the model, we introduced a method that checks the simulator version and returns whether the project is a Vue simulator project or not.
v0 and v1."legacy" tag.Step 3: Decide the embed path in the controller โ๏ธ In the Project controller, we used the helper method to set the correct embed path.
This kept the decision-making clean and consistent.
Step 4: Render the correct simulator in the view ๐ผ๏ธ
In the show page, instead of hardcoding the iframe path, we used the path determined by the controller.
This ensures that the correct simulator (legacy or Vue) is embedded based on the projectโs version.
simulatorVersion is missing.Here is the working of Embed ๐ฅ
For Pushing the vue-simulator we needed to change the old hash pointing to the vue-submodule in the primary codebase to the new hash pointing to the current vue-submodule. This step in theory was supposed to be just 2 steps:
cd into the cv-frontend-vue submodule from the master and use git branch to switch to mainBut the technicalities of the process overshadowed us and we ran straight into a wall. The Docker publish image workflow was failing! ๐จ It had to pass, else we couldnโt merge the PR (PR #6012). Now we had to review and fix it as soon as possible. This turned out to be trickier than we thought. It earlier seemed like just an issue due to missing v0 in the outdir. We tried fixing it that way but failed. Finally, after a lot more debugging, this is how we solved it.
Problem Statement: Docker build failed with โnot foundโ error when copying Vue simulator files from /public/simulatorvue/.
Root Cause: Vite config used relative path ../public/simulatorvue/ with undefined DESKTOP_MODE, causing unpredictable build output location.
Solution: (PR #6061)
/output/simulatorvue/DESKTOP_MODE=false for consistent Vite behavior# In simulator_vue_build stage:
RUN mkdir -p /output/simulatorvue
ENV DESKTOP_MODE=false
RUN npm run build
RUN cp -r public/simulatorvue/* /output/simulatorvue/ || cp -r ../public/simulatorvue/* /output/simulatorvue/
# In final stage:
COPY --from=simulator_vue_build /output/simulatorvue/ /usr/src/app/public/simulatorvue
Deliverable: Added an Authentication model to Tauri Simulator. For the Tauri simulator the users now will face an Authentication model specifically made for the application. They only have to login once, their profiles will be stored up until they themselves log out from the application. โ
Technical Tale: The reason we needed a separate Authentication model for vue simulator is because of Tauri. Earlier we were simply changing the path in the URL to direct to the Login page of Circuitverse for Authentication. This particular method fails for the Tauri simulator because:
To answer those needs, it was the need of the hour to create an authentication model for the vue-simulator and so did we deliver. The authentication system in the CircuitVerse frontend is built using Vue 3 with TypeScript.
It handles both login and signup flows via API requests to the CircuitVerse backend. ๐
POST /api/v1/auth/login ๐POST /api/v1/auth/signup ๐Auth Modal Handling ๐ช
authModal) is used to toggle between login and signup. ๐Form Validation โ
/.+@.+\..+/). ๐งRequest Building ๐ ๏ธ
isLoginMode), the request body changes:{ email, password } ๐{ name, email, password } ๐API Communication ๐
fetch function (via Tauri plugin when inside desktop app).State Management ๐๏ธ
useAuthStore()).Error Handling โ ๏ธ
401 Unauthorized โ Invalid credentials โ404 Not Found โ User does not exist ๐409 Conflict โ User already exists โ๏ธ422 Unprocessable Entity โ Invalid input ๐These are some of the snaps of the Authentication model and its working video-
Deliverable: Now the commits to the cv-frontend-vue require to follow conventional-commits ๐. This is to add more meaning to commits for both humans and machines ๐ค.
Why and How we did it: We have added conventional-commit to the workflows, ensuring smoothness in the Automation for version tag generation ๐. This also helps give the maintainers a good holistic view of where the simulator stands at, in turn helping them choose the minor, patch, or major version bump in the Release ๐ฏ. (PR #656)
From here on, the commits made by everyone would need to follow the conventional-commits โ
. Some of them are as follows:
The type indicates the nature of the change:
Deliverable: An Automated Release pipeline has been added to the vue-simulator. With one click by the maintainers a Release is created and assets (Artefacts for Windows, Mac and Linux subsystems) are attached with the Latest Release under Releases heading on cv-frontend-vue primary codebase. There is also another file called CHANGELOG that is created, it holds the logs of current and all of the previous Releases. ๐
How we did it? - One of the key deliverables for the GSoC project was a reliable release pipeline for the CircuitVerse desktop app. We initially explored fully automated tools like semantic-release and release-it!, but they offered less manual control than we needed. The ideal solution needed to balance powerful automation with maintainer oversight. โ๏ธ
The breakthrough was using GitHub Actionsโ workflow_dispatch. This allows us to trigger the release manually, providing input on the version type (major, minor, or patch), giving us the perfect blend of automation and control. This approach culminated in the final workflow that now powers our desktop releases. ๐ฏ
The entire process is encapsulated in a single GitHub Actions workflow file. Itโs composed of two primary jobs: build-tauri to compile the application across all platforms, and create-release to package and publish the final release. ๐ฆ
The workflow operates in two sequential jobs:
Job 1: build-tauri
This job is the workhorse, responsible for compiling the application. It uses a matrix strategy to run three parallel jobs, one for each target OS: ubuntu-latest, windows-latest, and macos-latest. This is the key to efficient cross-platform building. ๐
Environment Setup: Each job begins by checking out the code and setting up the required toolchains, like Node.js and Rust. Crucially, it also installs OS-specific dependencies needed for compilation, such as libwebkit2gtk-4.1-dev on Ubuntu or wixtoolset on Windows. ๐ ๏ธ
Dependency Caching: To dramatically speed up build times on subsequent runs, the workflow caches both the Node.js (.npm) and Rust (.cargo, target) dependency directories. This avoids re-downloading and re-compiling hundreds of packages every time. โก
Build & Upload: The job then runs the tauri build command, which creates the native application installers. Once complete, it uses the actions/upload-artifact action to save these installers, making them available to the next job in the workflow. ๐ค
Job 2: create-release
This job only runs after all three build jobs have completed successfully (needs: build-tauri). It handles the final packaging and publishing. ๐ฆ
Artifact & Code Aggregation: It begins by downloading all the build artifacts (the installers for Linux, macOS, and Windows) from the previous job. It also checks out the repository with fetch-depth: 0 to ensure it has the full git history, which is essential for the next step. ๐
Automated Changelog: The conventional-changelog-action scans the git history since the last release tag. Based on conventional commit messages (like feat:, fix:, etc.), it automatically generates professional, well-formatted release notes. ๐
Versioning: A bash script then determines the new version number. It fetches the latest git tag (e.g., v1.2.3), parses it, and increments the version based on the version-bump input (patch, minor, or major) that was provided when the workflow was triggered. ๐ข
Publishing: Finally, using the GitHub CLI, the script creates a new GitHub Release. It tags the commit with the new version, sets the release title, attaches the auto-generated changelog as the release notes, and uploads all the cross-platform installers as release assets. ๐
The Final Product (PR #636)โจ
The result is a beautifully simple and powerful release process. Now, any maintainer can go to the repositoryโs โActionsโ tab, select the โManually Triggered Desktop Releaseโ workflow, choose whether itโs a major, minor, or patch release, and click โRun workflow.โ ๐ฑ๏ธ

From there, everything is automated. Within minutes, a new, cross-platform release is published to GitHub, complete with installers for every OS and a professional changelog, ready for our users. This pipeline removes manual effort, eliminates human error, and ensures our releases are consistent and reliable every single time. โ

This has been the artistic side of the project. We have had the Testbench UI for a while now, up to now it had received 2 major UI revamps during some of the previous GSOC projects. This time we went outside the current colour palette a bit. We have used the classic Circuitverse green with white, which gives it a soft and user-friendly look. ๐๐ค
Here are some snapshots of the new Testbench UI ๐ธ

Here is a video showcasing the working of the new Testbench
Deliverable: This was a requirement for Versioning of vue-simulator. This is not a new feature but rather a major pillar of versioning. ๐๏ธ
And what is that major Pillar? After the previous yearโs GSOC project on implementing version control, we needed to sync the legacy simulator versions to the versioned folders while syncing the changes in the src folder to v0 and v1 too. This was carried out in 3 steps. ๐ ๏ธ
Step 1: This step was brute-force copying all of the files from the src folder to the versioned directories v0 and v1. ๐
Step 2: Then we compared all of the changes that existed in src and not in v0 and v1. We came across many small features that were missing for src which needed to be re-written, for eg: the version mismatch dialogue for the vue simulator in openOffline.vue. (PR #599) ๐ ๏ธ
Step 3: This was the part where we tested the result of the change. Since the change built up a massive PR, this step took time and also proved beneficial. We came across a few shortcomings, the major one being the preview circuits for version v1 going into infinite reload. This was created due to an error that occurred during the feature sync to the v1 folder. (PR #647) ๐๐
I learned a lot related to working of things in software. Most of all I learned how to look for solutions. I really liked the part where I sat plannig with my mentors as to how we are going to be approaching different contingencies. We implemented many ideas and had to leave behind many too. I learned a lot about GitHub Actions, Vue.js, Rust, and TypeScript a lot. Also got to try my hands on Rails and Ruby too. ๐ ๏ธ
These few weeks taught me a lot about how the industry works and how work is done. I learned a lot of things outside coding and got to meet many crazy people and learn from them. ๐
My journey so far has been nothing but a roller-coaster. Each week I stumbled upon things I didnโt know, then learned it, bugged my mentor about it, experimented with it and then implemented it. It has truly been a developerโs dream till now. My mentors and CircuitVerse community have been very helpful and inspirational in my little journey. Looking forward to contribute and learn more. ๐
I would especially like to thank my mentors Aryann Dwivedi and Niladri Adhikary for being amazing mentors and guiding my way out of the walls I kept head-butting into, I would also like to thank Arnab Das, Aboobacker MK, Vedant Jain and other mentors and circuitverse contributors for helping and mentoring me throught the journey. ๐๐