Computer science project ideas: 12 builds from regex engines to Raft
The best computer science projects rebuild a tool you already use, so you learn how it works inside: a regex engine, an interpreter, a key-value store, a DNS resolver, a Bloom filter, a text diff or a Raft cluster. Each maps to a course topic such as compilers, databases, networks or distributed systems. Below are 12 projects in five areas, each with the course it supports, a first version, a stretch goal, a test that proves it works and a time estimate.
What makes a good computer science project?
A good computer science project has a specification you can test against. Not “a nice app”, but “this program must match what the real one does on these 50 inputs”. That gives you a finish line and a reason to read the original paper or standard instead of a tutorial. It is also what separates a project that teaches you a data structure from one that just uses a library.
Pick the language you are most comfortable in unless the topic needs memory control, in which case use C, C++, Rust or Go. Each project below has an oracle: a real tool or a published test suite to compare against. Build the simplest version that passes the oracle, then do the stretch goal. If you want app-shaped projects instead, see coding project ideas, or for web topics, web development project ideas.
| Course | Project | Oracle to test against |
|---|---|---|
| Theory of computation, compilers | Regex engine | Your language's built-in regex on the same patterns |
| Programming languages | Interpreter | Programs from the book you follow |
| Databases | Log-structured key-value store, B-tree | A dictionary and a sorted list in memory |
| Operating systems | Shell with pipes | Your system shell on the same commands |
| Computer architecture | CHIP-8 emulator | Public test ROMs |
| Networks | DNS resolver, reliable transport over UDP | dig, and a file hash after transfer |
| Distributed systems | Raft cluster | Your own fault-injection tests |
| Algorithms | Bloom filter, diff, SAT solver | Brute force on small inputs |
Project: The real thing I am copying (tool, paper or RFC, with link): Inputs and outputs (exact formats): The oracle: how I will know my output is right: The smallest version that passes the oracle: Things I am skipping on purpose: The one concept I must be able to explain afterwards:
Which projects teach languages and compilers?
Parsing and execution are the oldest ideas in the field, and they are still the clearest example of theory turning into code. Both projects here produce a program you can type input into.
01 Regex engine that cannot blow up
Match patterns with literals, dot, star, plus, question mark, alternation and groups by turning the pattern into a state machine.
- Stack
- Any language.
- Teaches
- Finite automata, NFA simulation, parsing with precedence, why some matchers take exponential time.
- First version
- Parse to postfix, build an NFA with Thompson's construction, simulate it by tracking the set of live states. Pass 100 pattern and string pairs.
- Stretch goal
- Compile to a DFA on demand, add character classes, and measure against a backtracking matcher on a pattern built to hurt it.
- Time
- 15 to 25 hours.
Russ Cox's article Regular Expression Matching Can Be Simple And Fast walks through exactly this and explains why backtracking implementations can need exponential search in the worst case. Build the backtracking matcher first, in 20 lines, so you can feel it slow down. Then build the automaton and compare on the same inputs.
02 Interpreter for a small language
A tokenizer, a parser and an evaluator for a language with variables, functions, closures and control flow.
- Stack
- Any language.
- Teaches
- Lexing, recursive descent, abstract syntax trees, environments, scope, closures.
- First version
- Numbers, strings, variables, arithmetic, if, while, print. Runs a 30-line test program.
- Stretch goal
- Functions with closures, a clear error message with line numbers, then a second backend that compiles to bytecode for a small stack machine.
- Time
- 25 to 40 hours.
The free book Crafting Interpreters builds two interpreters for one language: a tree-walking one, then a bytecode virtual machine. Following it is a legitimate way to learn. Make it your own by changing something: a different syntax, or one new feature the book does not have. Write the test programs before the parser.
Help me build an interpreter in Python for a tiny language. Do it in stages and stop after each so I can read the code. Stage 1: a tokenizer for numbers, strings, identifiers, + - * / ( ) = ; and the keywords let, print, if, else, while. Show me tokens for 5 sample lines. Stage 2: a recursive-descent parser that produces a tree of small classes. Stage 3: an evaluator with an environment dictionary. Rules: no parser libraries, no eval(). Every stage has tests. Done when: tests/programs/*.tiny run and match the .expected output files.
Which projects teach storage and databases?
Databases are programs about disks. These two make you decide what happens when the power fails halfway through a write.
01 Log-structured key-value store
A store that appends every write to a file, keeps an in-memory index of where each key lives, and compacts old data in the background.
- Stack
- Go, Rust, C or Java; any language with file control.
- Teaches
- Append-only logs, hash indexes, checksums, crash recovery, compaction.
- First version
- set, get and delete over a single log file. On start, rebuild the index by reading the log. Every record has a length and a checksum.
- Stretch goal
- Segment files with compaction, a write-ahead guarantee with fsync, and a test that cuts the file mid-record and reopens it.
- Time
- 15 to 25 hours.
Test against an in-memory dictionary: run 100,000 random operations on both and compare. The interesting test is a truncated file. A half-written record at the end must be ignored, not crash the store. Measure how big the file grows when you overwrite one key a million times, then add compaction and measure again.
02 B-tree index on disk
A sorted key-value index stored in fixed-size pages, with insert, lookup and range scan.
- Stack
- C, Rust, Go or Java.
- Teaches
- Pages, node splitting, fanout, the cost of height, range scans, a file as an array of blocks.
- First version
- 4096-byte pages, integer keys, insert with splitting, lookup, in-order scan, all read through a page cache.
- Stretch goal
- Delete with merging, variable-length keys, and a comparison of your lookups against a sorted array.
- Time
- 25 to 40 hours.
Worked example: with 8-byte keys and 8-byte child pointers in a 4096-byte page, one node holds about 250 entries once you leave room for a header. Three levels then reach roughly 15 million keys, so a lookup reads three pages. That is why databases use B-trees. For a real layout to compare with, read how SQLite lays out its file: pages are a power of two between 512 and 65536 bytes.
Which projects teach operating systems and hardware?
These two sit closest to the machine. One is a program that launches other programs. The other is a program that pretends to be a computer.
01 Shell with pipes and job control
A command line that runs programs, connects them with pipes, redirects files and handles background jobs.
- Stack
- C, Rust, Go, or Python's os module.
- Teaches
- fork, exec, wait, pipe, dup2, file descriptors, signals, process groups.
- First version
- Run a command with arguments, support cd and exit as built-ins, handle > and < redirects, and a pipeline of two commands.
- Stretch goal
- Any number of pipes, & for background jobs, Ctrl-C that stops the running job but not the shell, and a jobs command.
- Time
- 15 to 25 hours.
Compare output with your system shell on 30 commands such as ls | wc -l. The classic bug is forgetting to close the unused ends of a pipe, so the reader never sees end-of-file and hangs. Finding that bug once teaches file descriptors better than a chapter does.
02 CHIP-8 emulator
An emulator for a tiny 1970s virtual machine, enough to play its games.
- Stack
- Any language with a window or a terminal display.
- Teaches
- Fetch, decode, execute, registers, memory maps, timers, bit manipulation.
- First version
- 4 KB memory, 16 registers, a 64 by 32 display and the 35 two-byte opcodes. Pass a public test ROM before trying a game.
- Stretch goal
- Sound, key mapping, configurable speed, a debugger that steps one instruction and shows registers.
- Time
- 15 to 25 hours.
The CHIP-8 overview lists all 35 opcodes, and the chip8-test-suite has ROMs that print which instruction is wrong. Use those instead of guessing from a game that looks off. Different emulators treat a few instructions differently, so test ROMs are the only fair referee.
Which projects teach networks and distributed systems?
Networks fail in ways that memory does not: packets are lost, repeated and reordered. These three make you write code that is correct anyway.
01 DNS resolver from scratch
A program that takes a hostname, builds a DNS query by hand, and follows the chain from a root server to the answer.
- Stack
- Any language with UDP sockets.
- Teaches
- Binary protocols, big-endian fields, name compression, recursion versus iteration, UDP.
- First version
- Build a query packet, send it to a public resolver, parse the answer section and print the A records.
- Stretch goal
- Iterate yourself: start at a root server from the IANA root hints, follow referrals to the answer, retry over TCP when the truncation bit is set, and cache by TTL.
- Time
- 12 to 20 hours.
The format is in RFC 1035: a 12-byte header, then questions and records. Names can point back to earlier bytes in the packet to save space, which is the part everybody gets wrong first. Compare every answer with the output of the dig command.
02 Reliable transfer over UDP
Send a file over UDP with sequence numbers, acknowledgements, timeouts and a sliding window, so it arrives intact over a lossy link.
- Stack
- Any language with UDP sockets.
- Teaches
- Reliability, retransmission, windows, round-trip timing, congestion basics.
- First version
- Stop-and-wait: send one packet, wait for its ack, resend on timeout. The received file's hash matches the original.
- Stretch goal
- A sliding window of 8 packets, a link simulator that drops 10 percent and reorders 5 percent, and an adaptive timeout.
- Time
- 15 to 25 hours.
Write the link simulator first. Without it your code works on a quiet loopback and fails the day it meets a real network. For the real design to compare with, skim RFC 9293, the TCP specification. Your protocol should be far simpler, and you should be able to say what it lacks.
03 Raft cluster in a single process
Five nodes that elect a leader, replicate a log of commands and keep working when you kill the leader.
- Stack
- Go, Rust, Java or Python with a fake network.
- Teaches
- Consensus, terms, leader election, log replication, safety versus liveness.
- First version
- Leader election only: randomized timeouts, vote requests, heartbeats. Kill the leader and watch another one win.
- Stretch goal
- Log replication with commit rules, a key-value state machine on top, and a test that partitions the network and heals it.
- Time
- 30 to 50 hours.
Start from the Raft site and its paper, which was written to be understandable, and use its RaftScope visualization to see what correct behavior looks like. Run your nodes as functions inside one process, with a fake network you control, so you can drop, delay and duplicate messages on purpose. Real sockets can come later.
Which algorithm projects are worth building?
The last three are classic algorithm ideas turned into tools. Each has a brute-force version that makes testing easy: run both on small inputs and compare.
01 Bloom filter with measured error
A set that answers “definitely not here” or “probably here” in a tiny amount of memory, with a false-positive rate you measure and compare to the formula.
- Stack
- Any language.
- Teaches
- Hashing, bit arrays, probability, space versus accuracy.
- First version
- Add and check strings. Insert 100,000 words, then test 100,000 words that were not inserted and count false positives.
- Stretch goal
- Counting filters that support removal, and a sizing function that takes expected items and wanted error rate.
- Time
- 5 to 10 hours.
As the Bloom filter overview notes, fewer than 10 bits per element give about 1 percent false positives. Worked example: for 1,000,000 items at 1 percent, use about 9.6 million bits, roughly 1.2 megabytes, with 7 hash functions. Your measured rate should land near 1 percent. If it does not, your hashes are correlated.
02 Text diff and patch
A tool that compares two files, prints the lines added and removed, and a second tool that applies that output to get the new file back.
- Stack
- Any language.
- Teaches
- Longest common subsequence, dynamic programming, edit scripts, memory-versus-speed trade-offs.
- First version
- A table-based longest common subsequence on lines, output in a simple + and - format. diff then patch returns the original.
- Stretch goal
- A linear-space version, grouping changes into hunks with three lines of context, and speed on 50,000-line files.
- Time
- 8 to 14 hours.
The diff overview names the algorithms that real tools use. Property to test with random inputs: for any two files A and B, applying diff(A, B) to A must give exactly B. Generate a thousand random pairs and check it. That single test finds most bugs.
03 SAT solver that solves a puzzle
A solver for yes-or-no formulas, used to solve a real puzzle you encode into it.
- Stack
- Any language.
- Teaches
- Boolean satisfiability, backtracking, unit propagation, NP-completeness made practical.
- First version
- Read the standard DIMACS text format. Implement DPLL: pick a variable, propagate forced values, backtrack on conflict. Solve 20 small test formulas.
- Stretch goal
- Encode 8-queens as 64 variables and solve it, then a 9 by 9 grid puzzle, and add a smarter choice of variable.
- Time
- 12 to 20 hours.
Check against brute force on formulas with up to 15 variables: both must agree on satisfiable or not. The encoding is where the learning is. For queens, say “at most one queen per row, column and diagonal” as clauses, and watch a general solver find the answer without knowing anything about chess.
Where do I find a project that solves a real problem?
From-scratch projects teach the most, and they are less useful as products. When you want the next step, build something for someone. The board at Post your build ideas collects ideas that people posted because they will not build them. Browse all ideas or the developer tools category, where several ideas need a real algorithm underneath, like parsing, diffing or ranking. Every idea has a generated build prompt for Claude Code, Cursor or Lovable. Posted does not mean validated; check with one person who has the problem.
For projects that show engineering practice instead of algorithms, see software engineering project ideas. To turn one of these builds into portfolio evidence, see portfolio project ideas.
Frequently asked questions
What is a good computer science project for a beginner?
Try a Bloom filter or a text diff. Both are small, have a brute-force version to test against, and teach a real data structure or algorithm in under 15 hours. A regex engine is a good next step, once you are comfortable with recursion and arrays.
What computer science projects look good to employers?
Ones that you can explain deeply. A key-value store with crash recovery, a shell or a DNS resolver shows you understand systems. Include a README with the spec you followed, the tests that prove it, and what you left out. Depth and honesty about limits read better than a long feature list.
Which programming language should I use?
Use the language you know best for algorithm and language projects. For storage, shell and network projects, a language with direct control of files, memory and sockets such as C, Rust or Go is a better fit, although Python works for learning the concepts.
How do I know my project is correct?
Use an oracle: a real tool or reference result to compare with. Run your regex engine against the built-in one, your shell against bash, your resolver against dig. For algorithms, compare with a slow brute-force version on small random inputs. Running a thousand random comparisons finds more bugs than reading your code.
Can I use an AI coding tool for these projects?
Yes, but use it to speed up the parts you already understand. Ask it to work in stages, read each stage, and write the tests first. If a stage includes code you cannot explain, ask for an explanation or rewrite it yourself. The aim of these projects is to learn the idea, not to own the file.
How long do computer science projects take?
The first version of the smaller ones takes 5 to 15 hours. Interpreters, B-trees and Raft take 25 to 50. Spread them over several weekends, finish with the oracle test passing, and stop there. A finished first version teaches more than an unfinished ambitious one.
Created with AI assistance and edited for this site. Examples are illustrative and do not represent customer research. About the publisher.