Inside PDP Shikshya's In-Browser Coding Academy
Inside PDP Shikshya's in-browser coding academy: 104 grade-banded courses, 3,533 lessons, and a live editor running Python, SQL, JS and React client-side.
At pdpspectra we build learning and operations platforms for an international audience, and the most useful thing about doing that work across markets is that the hard constraints surface fast. Schools do not want another video library. They want students to do something and have the platform prove they did it. That is the design goal behind the coding academy inside PDP Shikshya, our EdTech product — and this post is the engineering walkthrough of how it actually works, with the real numbers pulled straight from the codebase.
If you want the wider context first, start with the platform overview, the Socratic tutor deep-dive, and the School Management System post. This one zooms into a single feature: the hands-on, W3Schools-style academy with a live in-browser editor.
What the academy actually is#
The academy is a self-paced catalogue of 104 courses carrying 3,533 lessons, organised into 13 categories — Web Development, Programming, Data and Databases, Office and Productivity, Tools, Computer Science, Academics, Social Studies, Exam Prep, Life Skills, Stories and Reading, Simulations, and Fun and Games. That spread is deliberate. Pure coding tracks (HTML, CSS, JavaScript, Python, SQL, React, Node.js, C, C++, Java, TypeScript, PHP and more) sit next to grade-banded academic courses — Mathematics 6 to 8, Physics 8 to 10, Chemistry 10 to 12, and SEE and NEB exam-prep tracks aligned to the local curriculum.
The grade banding is the part most coding sites skip. Each course tile carries a level (for example “Class 8 to 10”) and a category, the catalogue supports search by name and filter by category, and every tile shows a progress ring so a student sees how far they have come. A child in grade 7 and a student revising for a board exam are not handed the same wall of content; the banding routes them to material pitched at where they are.
These are not numbers from a slide. They come from the course registry the frontend actually ships (frontend/src/content/courses/index.js), where each course declares its lesson_count and category. The figures here are the live totals from that file, not a marketing estimate.
The Try-It editor: real code, no server#
The centre of the academy is the Try-It editor — a live, in-browser code runner. A lesson ships with starter code, the student edits it in place, hits Run, and sees the result immediately. The important engineering decision is that nothing runs on a backend. Every supported language executes entirely client-side. There is no remote sandbox to provision, no per-student container to spin up, and no code-execution endpoint to secure. That matters for cost, for latency, and for a security surface you do not have to defend.
Four runtimes back it, each chosen to fit the language:
- HTML, CSS and JavaScript render into a sandboxed
iframe. The preview frame is created withsandbox="allow-scripts allow-pointer-lock", so student code runs isolated from the host app — it cannot touch the parent page, its cookies, or its session. - Python runs on Pyodide, CPython compiled to WebAssembly. The student’s code executes in the browser tab; we capture
stdoutandstderrand stream them into an output pane. - SQL runs on sql.js (SQLite compiled to WASM) against a seeded sample
studentstable, so a learner can write realSELECT,JOINandGROUP BYqueries and get a rendered result grid back — no database to connect to. - React is transpiled in the browser with Babel standalone and rendered against React 18 loaded from a CDN, inside the same sandboxed iframe approach as the web runner.
Languages without a browser runtime (C, C++, and similar) fall back to a study mode: the editor is still there to read and tinker with, but the Run button is disabled and labelled honestly rather than failing silently.
The engineering details that make it hold up#
Two problems show up the moment you put live code in a single-page app, and both are handled in the editor component (frontend/src/pages/courses/TryItEditor.jsx).
The first is re-running scripts after client-side navigation. Reusing one iframe and merely reassigning its srcDoc does not reliably re-execute the page’s scripts when a student moves between lessons without a full reload. The fix is to remount the preview iframe with a changing React key on every run, so a freshly mounted frame always runs the code. It is a small detail that is the difference between “Run does nothing” and “Run works every time.”
The second is boot cost. Pyodide and sql.js are heavy WASM runtimes. We load each one once per page session, cache the instance, and guard against double-injecting the CDN script tags — so the first Run pays the load cost and every Run after that is instant. The student sees a clear “Loading Python, this can take a few seconds” status on that first boot instead of a frozen button.
This is the kind of thing that separates a demo from a shipped feature. A live in-browser editor is easy to prototype and fiddly to make reliable across navigation, slow networks, and older devices. The academy is built for exactly those conditions.
Lessons built to be understood#
Running code is half of it; understanding it is the other half. Every lesson is broken into bite-size blocks, and two of them are aimed squarely at students learning in a second language.
An “In simple words” block restates the concept in plain language, stripped of jargon. And code blocks support an “explain each line” mode that pairs every line of a snippet with a short note on what it does — so a student is never staring at an opaque block of syntax wondering which part did what. For a learner whose first language is not English, that line-by-line scaffolding is often the thing that makes a concept click.
Each lesson can close with a quiz, and the pass mark is 60% (defined as a single PASS_MARK constant, so it is consistent across every course). The quiz component reports a pass back to the lesson exactly once, when the student first clears the bar, which keeps progress writes clean and idempotent. Progress is tracked per lesson — best quiz score and completion ticks — and rolls up into the catalogue progress rings. The backend exposes this through a feature-gated courses progress API, so a student’s place in the academy persists across devices the same way their tutor history does.
The editor itself is also built for genuine use, not just display. A student can Run, Reset back to the lesson’s starter code, and Copy the snippet, and every label is bilingual — English and Nepali — because the entire app is. The output pane adapts to the language: HTML, CSS, JavaScript and React get a full-width live preview frame, Python gets a streamed text console, and SQL gets a rendered results table with proper NULL handling. A student writing their first SELECT sees columns and rows come back the way a real database client would show them, which is a far better mental model than a wall of printed text.
Shipping it without slowing the app down#
A catalogue of 3,533 lessons is a real payload problem. If all of that content shipped in the initial bundle, the app would crawl on the mid-range Android phones that are the reality in many of the markets we build for. So the academy is built around on-demand loading.
The catalogue grid carries only lightweight metadata for each course — name, level, category, lesson count, blurb. The heavy lesson content lives in per-course modules that are split into separate chunks and fetched only when a learner opens that course, using Vite’s import.meta.glob to wire up lazy importers, with resolved courses memoised so re-opening one is instant. That sits on top of route-level code-splitting across the whole frontend — pages are loaded with React’s lazy and Suspense, so the academy’s weight never lands on a student who never opens it.
Around the editor sit media viewers — dedicated PDF, image, audio and video components — backed by S3 storage for the media a school uploads. The academy is also wired as a per-school feature toggle: a school that wants it switches it on, and a school that does not never sees it. That toggle lives in the same multi-tenant, role-based platform that runs the rest of PDP Shikshya, where every school is an isolated tenant.
Where this fits#
We did not build a standalone coding site. The academy is one module inside a School ERP that already runs attendance, homework, routines, report cards, analytics, and an AI Socratic tutor — and that integration is the point. The same platform that handles a school’s Operational Automation also gives its students a place to write and run real code, and gives the school a single system to administer instead of five disconnected tools.
That is how we approach every build at pdpspectra: AI implementation and Data Platforms grounded in what the operation actually needs, shipped as one coherent product rather than a pile of features. The coding academy is a clean example — a genuinely hard piece of frontend engineering (a reliable in-browser multi-language runtime) made to disappear behind a Run button a student can use without thinking about any of it.
Want a learning platform that ships real capability, not a slide deck? See the product at pdpshikshya.com, or talk to us about your build at pdpspectra.com. AI-powered. Data-driven. Built to ship.