Inspiration

jQuery is still everywhere. Old company sites, freelance projects and a lot of student projects still run on it. Everyone knows they should move to React, but nobody wants to rewrite it by hand. It's slow, boring, and easy to break without noticing.

I wanted to see if an AI agent could do the boring part, and, more importantly, prove that the result actually works instead of just hoping it does.

What it does

You paste the GitHub link of a small jQuery app. Legacy Modernizer then:

  1. Clones the repo and checks that it really is a jQuery app.
  2. Plans the migration. Nemotron 3 Ultra reads the whole codebase at once and writes a file-by-file plan, grounded with current docs from Tavily.
  3. Rewrites each file into React with Nemotron 3 Super.
  4. Verifies the result in a real Nebius Token Factory Sandbox: it runs npm run build and ESLint on the migrated app.
  5. If something fails, the real error output goes back to Super, which fixes the file and tries again (up to 3 tries for the build and 3 for lint).
  6. When it passes, you download the whole app as a zip and run it with npm install && npm run dev.

You watch all of it live in the browser. If a few files time out, you can retry only those files instead of starting over.

How I built it

  • Backend: Python and FastAPI, streaming progress to the browser with Server-Sent Events.
  • Frontend: React, TypeScript and Vite.
  • Models: Ultra for planning, because its long context lets it see the entire repo at once. Super for rewriting and fixing files, because it's faster. Everything runs through Nebius Token Factory.
  • Sandboxes: every attempt builds and lints in a clean sandbox checkpoint with dependencies already installed, so a failed attempt never pollutes the next one.
  • Tavily: gives the planner current migration docs instead of relying on what the model remembers.

Challenges

Most of the project was dealing with a model that isn't predictable.

  • The planner sometimes listed files that don't exist, repeated the same file many times, or skipped the main script. I added checks that drop fake files, remove duplicates and re-add anything important that was missing.
  • When fixing build errors, the model liked to split code into a new file, which didn't exist and broke the build again. Now I detect that and force the fix to stay in one file.
  • Early migrations lost their styling, because the model only saw the JavaScript and never the original HTML. Giving it the original page structure and keeping the CDN stylesheets fixed most of it.
  • The default 10-minute SDK timeout made the app look frozen. Shorter timeouts and retries fixed it.
  • A passing build doesn't mean good code, so I added ESLint as a second check.

What I learned

Prompts alone aren't reliable. What worked was small deterministic checks around the model, plus running the code for real in a sandbox, so the agent fixes real errors instead of guesses.

Limits and what's next

It works best on small and medium vanilla jQuery apps. Large multi-page apps with many plugins are still hard for it, and it keeps the original app's behavior, including things like dead API keys. Next I'd like to support more frameworks and open a pull request directly instead of giving a zip.

Built With

  • docker
  • eslint
  • fastapi
  • git
  • nebius-sandboxes
  • nebius-token-factory
  • nemotron-3-super
  • nemotron-3-ultra
  • nvidia-nemotron
  • python
  • react
  • render
  • server-sent-events
  • tavily
  • typescript
  • vercel
  • vite
Share this project:

Updates

Submission history