SQL Valley
SQL Valley lets students practise SQL without installing a database or creating an account. I helped turn an early prototype into a React and TypeScript application, working on the SQL editor, answer checking, and saved progress. My contribution ran from August 2025 to August 2026, with a handover in September.

A join exercise on the live site, with a query running against the small teaching dataset. The names and positions are sample data.
View full sizeSQL Valley, developed with TU/e. Source and MIT licence.
I worked with Hildo Bijl at TU/e, who guided the educational design and reviewed the architecture. Alexandra Boala worked on the skill-tree interface, and Razvan Efros contributed exercises and sample data. My focus was the application and the infrastructure behind the learning experience.
Checking an answer
Two different SQL queries can answer the same question. The checker runs the student's query and a reference query against the exercise database, then compares the resulting tables. SQLite runs in the browser through SQL.js; CodeMirror provides the editor.
I moved exercise checking into a shared result-comparison implementation. The comparison rules depend on what the exercise teaches: row order matters when practising sorting, while a different column order may be fine elsewhere. Invalid SQL gets an error; a valid query with the wrong result gets feedback and another attempt.
Keeping progress when content changes
Saving entire exercises in the browser left learners with old prompts and solutions after content updates. I changed persistence to keep an exercise's identity and version alongside the learner's input and progress, and resolve the content from the current definitions.
The migration kept module progress but discarded old attempts that could not be restored under the new format. That was a deliberate limit on what we carried forward.
Separating the engine from SQL
Later work separated the general exercise lifecycle from SQL execution and grading. The application supplies the curriculum and storage; the engine manages an exercise without importing the site's concrete content.
I introduced a storage adapter before extracting the engine and related tools into workspace packages. Moving files alone would have left the dependencies tangled. Hildo took over further development after the handover, and the project has continued to evolve.