CodeJeet: a static site that indexes company-wise LeetCode questions
🍿 15K+ Company-wise LeetCode Interview Questions and System Design. Filter by company, topic, and difficulty.
At a glance
- What is it?
- CodeJeet is a Next.js static export that turns 663 per-company CSV files of interview questions into one browsable, filterable index with progress tracking kept in the browser, a system design chapter set and a blog, deployed to Cloudflare Pages with no API, database or authentication of its own. It suits a candidate preparing for interviews who wants to see which problems a given company actually asks, and the interesting engineering is in the build-time CSV to JSON step rather than in the runtime, which is a static bundle and a localStorage key.
- Who is it for?
- Adopt CodeJeet as a preparation tool if you want a browsable index of which questions companies ask, and use it locally with pnpm dev rather than assuming a hosted copy is current.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One JSON file built from 663 CSVs at build time
CodeJeet browses 17,000+ company-wise LeetCode interview questions from 660+ companies, and the README describes the whole runtime in three short sentences. Question data lives in 663 CSV files in `data/companies/`, one per company. At build time, a prebuild script parses all CSVs into a single `public/data/questions.json`. The dashboard fetches this JSON client-side and caches it in localStorage.
Then the summary: no API routes, no database, no auth, everything is statically generated.
That is the design decision that makes the project what it is. The data is large enough that shipping it as one JSON file and caching it in the browser is the obvious move, and the prebuild step in the package manifest is where the work happens:
pnpm run prebuild # generates public/data/questions.json from CSVsThe prebuild script chain is longer than that one command, and the chain is instructive. It runs `tsx scripts/build-data.ts` for the questions, then `tsx scripts/verify-dashboard-data.ts`, then `tsx scripts/build-blog.ts`, then `tsx scripts/build-system-design.ts`, and finally `tsx scripts/build-sitemap.ts`. So the build produces four different kinds of derived content, the same way, with the verification step sitting between the data build and the rest.
That verification script is the detail worth noticing. Building a single JSON blob out of 663 separate files is exactly the operation where a malformed row, a missing company or a stray encoding difference becomes a silent hole in the data. A separate script that checks the dashboard data after it is built is the kind of thing a project adds after it has been bitten once.
The project structure listing shows the same discipline in the layout:
app/ Next.js App Router pages
components/ React components (shadcn/ui + custom)
ui/ shadcn primitives
magic-ui/ animation components
lib/ data loading, stores, SEO, utilities
data/companies/ 663 CSV files (one per company)
public/system-design/ 16 markdown-based chapters
content/ blog markdown files
scripts/ build-data.ts (CSV → JSON prebuild)There is also an import script, `import:data`, which runs `node scripts/import-liquidslr.mjs`, and the README credits the source of the company-wise data to the liquidslr/interview-company-wise-problems repository. So the CSVs themselves are imported, not authored here, and there is a `scraper/` directory at the repository root for the collection tooling.
The features are filters, and the progress tracker is a localStorage key
The feature list reads like a checklist of a data browsing application, and the notable one is the last.
Company-wise questions come with frequency-sorted questions for 663 companies, the list naming Google, Amazon, Meta, Apple and Microsoft. Filtering works by company, by difficulty of Easy, Medium or Hard, by topic, by premium status and by timeframe. Full-text search runs across titles, companies and topics. Company comparison puts the question sets of two companies side by side, which is the feature that answers a question the plain list cannot: what does this other company ask that this one does not.
Then progress tracking, and the README is precise about the mechanism. You checkbox each question, and it is persisted in localStorage. There is no account, no sync and no server. That is a deliberate consequence of the static architecture rather than a missing feature, and it has the obvious trade: your progress lives in one browser profile on one device, and clearing site data loses it.
The rest of the list is content rather than function. There is a system design section of 16 chapters covering scaling, rate limiting, consistent hashing, a URL shortener, chat systems and more, and a blog of 2,700+ articles on DSA and interview preparation. The audiobook player for The Accidental CTO is a third content block, which is the piece most likely to surprise anyone expecting a pure problem index.
The tech stack explains the visual side. Next.js 16 in static export mode with React 19, TypeScript throughout, Tailwind CSS with OKLCH colour tokens, and shadcn/ui in the new-york style over Radix primitives, with Cloudflare Pages for deployment.
The component tree in the structure listing shows a `magic-ui/` directory for animation components alongside the `ui/` directory of shadcn primitives, so the animation work is a separate set of components rather than a property of the base ones.
Running it locally, and the build that needs six gigabytes of heap
The development commands are short, and the one that matters is the prebuild.
# Install dependencies
pnpm install
# Run dev server (Turbopack)
pnpm dev
# Build for production
pnpm run prebuild # generates public/data/questions.json from CSVs
pnpm build # static export to out/
# Lint & format
pnpm lint
pnpm formatThe build script sets a heap limit explicitly, `NODE_OPTIONS='--max-old-space-size=6144'`, which is six gigabytes. That number is a direct consequence of the design: a single JSON file holding seventeen thousand questions with their company and topic lists, built by parsing 663 CSVs in one Node process, is a memory-hungry job, and the flag tells the runtime to allow for it rather than failing with an out-of-memory error.
The deployment side is separate from the static side, and that is worth understanding. The README's deployment section lists three scripts for Cloudflare, `build:worker` to build for Cloudflare, `preview` for a local preview with Wrangler, and `deploy` to deploy to Cloudflare Pages. The `build:worker` script is `opennextjs-cloudflare build --minify` followed by two scripts, `prune-worker-assets.ts` and `check-worker-assets.ts`, so the worker build is a separate artefact from the static export, and the assets are pruned and then checked.
That distinction between the static export and the worker is the one apparent tension in the project, and the rest of the configuration explains it. The static export serves the question data, the blog, the system design chapters and the search. The worker is what serves the parts that need a server: signed-in progress and notes.
The environment file makes the split explicit. The Clerk publishable key is marked optional and only needed to save progress or notes cloud sync, with the secret kept runtime-only. The `DATABASE_URL` is marked as required for signed-in progress and notes. `USER_DATA_READ_ONLY=0` is set to 1 only during the final migration sync, with reads remaining available, which is a maintenance flag rather than a runtime one.
The Docker image, the health check and the user data migration
The Dockerfile is a Next.js standalone build on Alpine, and a few details in it are worth naming.
The base is `public.ecr.aws/docker/library/node:22-alpine`, with corepack enabled so that pnpm is available without installing it separately. The dependencies stage copies only the three package files and runs `pnpm install --frozen-lockfile`, which is the standard way to make a Docker layer cacheable on a lockfile that has not changed.
The builder stage takes three build arguments, `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY`, `NEXT_PUBLIC_R2_BASE_URL` and `NEXT_PUBLIC_GA_MEASUREMENT_ID`, and passes them as environment variables for the build. That matters because they are all `NEXT_PUBLIC_` prefixed, and those are inlined into the client bundle at build time. The consequence is that changing a Clerk key or a measurement id means a rebuild, not just a restart, and the Docker build has to be told the values.
The runner stage sets `NODE_ENV` to production, `HOSTNAME` to 0.0.0.0 and `PORT` to 3000, and creates a system user and group with uid and gid 1001. It copies the standalone output, the static directory and the public directory, all with the ownership set to that user, and then runs as that user rather than as root. The health check is a wget against the health endpoint on a thirty second interval with a twenty second start period, and the container command is the standalone server.
The user data side has its own lifecycle, and the scripts reflect a deliberate migration rather than a feature. `migration:import` runs `tsx scripts/migrate-user-data.ts import` and `migration:verify` runs the same script with verify. The `USER_DATA_READ_ONLY` flag is the corresponding runtime control, set to 1 only during the final migration sync while reads remain available.
The rest of the scripts show a project with its tooling in place: `knip` for unused exports, `oxlint` and `oxfmt` for linting and formatting, `husky` for the git hooks, `lint-staged` for staged changes, and the test script running `tsx --test` over the test files.
What this is, and what a similar project would do differently
The comparison worth making is with the other way to get company-wise question data, and with a conventional web application of the same kind.
The other way is to build the index yourself from the source dataset. The import script exists precisely for that, and the data is credited to a separate repository, so building your own version means running one import command and writing a viewer. If you want the data and not the site, that is the cheaper path, and it avoids inheriting a site's opinions about what a good preparation workflow looks like.
Against a conventional web application, the difference is that this one has no server for its main content, while still having a server for the parts that need one. That is an unusual shape for a project with a login, a database and a blog, and it produces the two-build arrangement described above, with a static export for the reading experience and an OpenNext worker for the signed-in features. A team that does not need cloud sync of progress gets the static half and nothing else.
The localStorage progress tracker is the clearest expression of that bargain, and it has the practical consequence worth stating. A checkbox in localStorage cannot be shared between a phone and a laptop, cannot be recovered after clearing browser data, and cannot be attached to a profile. For a candidate using one device that is entirely acceptable, and for someone syncing across devices it is a real limitation with a documented alternative in the project itself, the signed-in sync through Clerk and PostgreSQL.
The deployment story is the other thing that sets this project apart from a static site generator setup. The static export is the fast path, but the Cloudflare worker path with asset pruning and verification exists because the app has outgrown a purely static deployment, and the build scripts, the health check and the migration flags are the evidence of that. The project is also young in the visible metadata, with the package version at 0.6.9.
Editorial conclusion
Adopt CodeJeet as a preparation tool if you want a browsable index of which questions companies ask, and use it locally with pnpm dev rather than assuming a hosted copy is current. Do not treat it as a source of truth for a company process, because the data is a third-party dataset imported from liquidslr/interview-company-wise-problems and check first whether the optional Clerk and PostgreSQL configuration is something you want, because the env file shows the static experience needs neither while signed-in sync needs both.
Frequently asked questions
What is CodeJeet?
It is a Next.js static export that lets you browse 17,000+ company-wise LeetCode interview questions from 660+ companies, with filtering by company, difficulty, topic, premium status and timeframe, full-text search, progress tracking in localStorage, a company comparison view, 16 system design chapters and a blog. The homepage is codejeet.com and the licence is GPL-3.0.
How does CodeJeet load its question data without a server?
Question data lives in 663 CSV files under data/companies, and a prebuild script parses them into a single public/data/questions.json at build time. The dashboard fetches that JSON client-side and caches it in localStorage, with no API routes, no database and no auth for the main experience.
Where does the CodeJeet company question data come from?
The README credits the company-wise interview questions to the liquidslr/interview-company-wise-problems repository, and the package manifest includes an import:data script that runs scripts/import-liquidslr.mjs. A scraper directory sits at the repository root for the collection tooling.
How do I run CodeJeet locally?
Run pnpm install and then pnpm dev for the Turbopack dev server. For a production build, run pnpm run prebuild first, which generates public/data/questions.json from the CSVs, then pnpm build for the static export. The build script sets a six gigabyte Node heap limit.
Does CodeJeet need a database to track progress?
Not for the basic experience, since progress is a checkbox persisted in localStorage. Cloud sync of progress and notes needs the optional Clerk publishable key, the Clerk secret and the DATABASE_URL for PostgreSQL, and the USER_DATA_READ_ONLY flag is used only during the final migration sync while reads stay available.
Is CodeJeet still being developed?
The repository is not archived and the last push was on 2026-10-19. There are no GitHub releases, the package version is 0.6.9, with a separate set of scripts for the Cloudflare worker build and a user data migration with import and verify commands.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ayush-that-codejeet)Was this useful?