A VS Code–style SQL query editor UI, built for Atlan's Frontend Engineer take-home challenge — multi-session query management with a visual query builder and exportable results.
A single-page SQL editor with a sidebar for managing multiple query "sessions" in parallel, each independently cached and searchable. Users can hand-write SQL or assemble it visually through a Select/From/Where/Group By/Having query builder, run multiple queries in one session, and export any result set as CSV or JSON. All session state persists to localStorage, so nothing is lost on refresh.
Note: query execution is mocked — this was a frontend-only challenge, so "running" a query returns a random cached result set rather than hitting a real database. The state management, persistence, and UI logic are all real.
useSessions(custom hook) — owns all session state (query text, cached result IDs, timestamps), reads/writes tolocalStorageon every change, and exposesaddSession/updateSession/removeSessionApp.jsx— top-level layout; wires the sidebar, editor pane, and results pane together and owns the "run query" logic (splits on;, resolves how many new results are needed vs. already cached)QueryBuilder— controlled form (Select/From/Where/Group By/Having) that compiles user input into a SQL string and appends it to the active session's queryPastSessions— searchable, renameable list of sessions; filters by session name or query text as you typeResult— renders a mocked result set as a table and exposes CSV/JSON export viaBlob+ object URL downloads
git clone https://github.com/rk1091/sqly.git
cd sqly
yarn install
yarn devRuns locally on Vite's dev server (default http://localhost:5173). No environment variables or backend needed.
yarn build # production build
yarn preview # preview the production buildLive version: https://sqly.netlify.app/
- Designing state that needed to survive both in-memory updates (typing) and persistence (localStorage) without fighting React's render cycle — solved by centralizing all mutations through one
updateStatefunction in the hook rather than scatteringsetState+localStorage.setItemcalls across components - Handling multi-query sessions: a session can contain several
;-separated queries, each needing its own cached result, added or dropped incrementally as the user edits — this meant diffing "how many results does this session need now vs. before" rather than re-running everything - Keeping the query builder and the raw text editor in sync as two views of the same underlying state, so a user can freely switch between visual building and hand-editing without losing work