P2: Alpha (MVP)
| Milestone | Due date |
|---|---|
| Overview | |
| P1: Design | Monday, October 5, 2026, 11:59 PM |
| P2: Alpha (MVP) | Tuesday, October 13, 2026, 11:59 PM |
| P3: Beta (complete functionality) | Monday, October 19, 2026, 11:59 PM |
| P4: Code complete | Monday, October 26, 2026, 11:59 PM |
| P5: User testing | Monday, November 2, 2026, 11:59 PM |
Due Tuesday, October 13, 2026, at 11:59 PM.
Overview
Implementing a full-stack web app. In this assignment, you will build a working version of your app. You will acquire all the basic implementation skills needed to take your project from design to working software. You will become familiar with the architecture of a full-stack web application: how a reactive front-end works, how requests and responses are passed between the front-end and the back-end, how requests are handled, and state is persisted in a back-end database. All this will enable you to make sense of any web application that you come across.
Concept structuring. In addition, you will learn how to structure the back-end with concepts, achieving a level of modularity and reuse that is not yet common. You will also learn how to express control and data flows with reactions, turning what would be complex route handlers into declarative rules that give more transparency and that factor out application-specific functionality.
Minimum viable product (MVP). Rather than building the entire application at once, you will first (in this assignment) build a subset of the functionality. This subset, known as an MVP, is a fully working, coherent version of the application that may lack features needed for the application to be practical in all contexts, but which nevertheless illustrates its essential behavior. Building an MVP first is useful for many reasons. It gives you a version of the app to demonstrate early on, so that others can assess its potential; in a start-up, the MVP is what you might show to a VC or to your first customers. The MVP gives you a chance to test the hypothesis that your app actually mitigates a bad situation that matters, and does so effectively, giving you time to adjust your design and problem focus if it turns out to be less compelling than you’d hoped, or needing additional functionality that you had failed to anticipate.
Core user journey. To scope your MVP, you will define a core user journey: a scenario in which one or more users exercise the app to experience the essential functionality of your MVP. This user journey should be complete in the sense that it includes all set up that is necessary; the database should be assumed to be empty at the start. It does not need to handle errors or edge cases. You will implement the concepts, reactions, and front-end components needed for this journey. Your MVP may be rough around the edges; the full functionality will come in a later assignment.
Incremental development. In this project, you will gain experience developing an application incrementally. Working incrementally, one small step at a time, has come to be recognized as the most reliable and cost effective way to ensure that progress is being made. (It’s the basis of the agile process, a widely used approach for organizing software development timelines.) We have also found in many years of teaching that the most common cause of failure in student projects is trying to do too much at once, and not working incrementally. If you work incrementally, you can build up your understanding one small step at a time; test your work as you go; and avoid doing a lot of work that needs to be undone because it turned out to have been misguided.
Using an LLM. Working incrementally is especially important in the presence of LLM coding agents, because it’s easy to ask an LLM to one-shot your entire application, and then find that you have a repository full of code that you don’t understand at all. An LLM will also be much more effective making one change at a time, and by making small changes and testing each as you go, you can ensure that your application doesn’t become riddled with errors. Using an LLM for agentic coding is recommended but not required. Sync engine (see below) includes background and guidance documents so there is no need to provide additional context for concept-based coding. For advice on choosing a coding tool and accessing free student plans, see How to choose an AI coding tool.
Running locally. The result of this assignment will be a locally-running app. In the next assignment, you will deploy your app online to a publicly accessible URL, which will allow you to share it with friends and colleagues.
Platform components. You will use Bun for the web platform, MongoDB for your database, and Vue.js for your frontend. Rather than coding concepts and reactions directly in Typescript, you will use sync-engine, a framework developed here at MIT.
Sync engine. Sync engine offers several benefits. First, it implements a lightweight engine for executing reactions (or “syncs”, hence the name), not only managing the control and data flow between actions but also giving you library functions that let you write reactions in code in a way that closely mirrors the way they are expressed as declarative rules. Second, it ensures conformance to the concept design modularity principles, ensuring for example that there are no calls between concepts, so that concepts remain polymorphic and reusable. Third, it enforces an emerging programming paradigm called “specification-driven development” in which every code component has a corresponding specification component. This makes it much easier to understand the behavior of the app and the way the code works, since each component is properly documented and explained. This becomes especially valuable when using an LLM because it prevents the LLM from modifying the code in undocumented ways. It does mean, however, that if you write the code yourself you will also need to make sure that there are corresponding specification files. Fourth and finally, sync engine automatically creates a typed library for making calls to the backend API; by using this library in the front end, the common kind of error in which front-end requests do not match the back-end API are eliminated.
Tasks
The steps to implementing your app are:
- Outline your user journey in prose.
- Set up sync-engine in your repo.
- Bring in your design specifications from the previous assignment in the “design/” folder.
- Make a plan for how you will implement your solution incrementally, which you will then execute by writing:
- TypeScript implementations of concepts including the Mongo operations.
- Reactions that compose actions, and views that lookup state.
- Endpoints that wire HTTP requests to actions, and formers that format responses to those requests.
- A Vue.js frontend that interfaces with the endpoints.
- Record a brief demonstration of your working app.
As you go, record design notes to document your progress (significant decisions, challenges, future work) in your personal repo. Steps will be iterated as you develop your application incrementally; you will be expected to demonstrate this incremental work in your design notes. (Even if you intended to progress in a straightforward linear fashion, you would be unlikely to do so. You will have to go back to previous steps and change your implementations—and even your concepts—as you evolve your understanding of the design. This is the nature of all design.)
The rest of this section contains details to help you complete each step.
User journey
Devise a core user journey that captures the essence of your project while perhaps involving only part of its functionality. You can think of this user journey as your app’s “elevator pitch.” You may re-use your user journey from P1 if you’d like, or come up with a new one. By the assignment deadline, your prototype must be, at a minimum, capable of demonstrating this user journey. It’s okay if the prototype is rough around the edges and isn’t fully polished visually. Your final app may differ substantially from this prototype in its visual appearance.
Set up your repo
Follow the tutorial to set up sync-engine in your repo.
Backend implementation
You will complete this section using the sync-engine framework. The documentation of the sync-engine is dense and not always easy to read. We recommend directing an LLM agent at the documentation and asking for guidance on each step of the backend implementation.
- Specifications. Copy your designs (concept and reaction specifications) into the design/ folder. Make sure your specifications are formatted correctly.
- Concepts. In TypeScript, implement the concepts relevant to your user journey, along with a suite of test cases for each concept.
- Endpoints. Register API endpoints suitable for your user journey.
- Reactions. Implement the necessary reactions, conforming to the domain-specific language specified in the background document for sync-engine.
- Formers. Write the formers your endpoints will use.
- Views. Write the views your reactions will use.
Frontend implementation
Using Vue.js, produce a minimal frontend that calls the endpoints you defined in the backend in order to fulfill the user journey. Reference the Prep on Vue for help.
The separation of frontend and backend allows us to defer concerning ourselves with one while we focus on the other. For this assignment, the emphasis is on setting up our backend and essential frontend functionality. In later assignments, we will pay close attention to effective frontend design.
Incremental work
As explained in the overview above, you should build your implementation incrementally. Your design notes should include an initial plan that you formulated for an order of implementation, and how you adjusted this plan as you progressed. The plan itself should be brief (less than half a page of text), but it should make clear what the key steps are and how you intend to evaluate the result of each step.
Screen recording
Make a screen recording (maximum two minutes long) where you use your app and demonstrate the user journey. Provide a narration describing the user journey as it takes place. You can use any tool you’d like to make the screen recording. (For instance: QuickTime Player on Mac can simultaneously record a video of your screen and audio from your microphone; on Windows, the Snipping Tool documentation can record a video of your screen and lets you add audio after.)
Deliverables
Your working MVP implementation (frontend Vue.js and backend sync-engine).
A one-paragraph informal outline of your user journey.
Your screen recording. Note that you should not spend a lot of time preparing this; its purpose is just to allow the staff to assess how your work is progressing.
Your design notes, including your plan, significant decisions, design changes, challenges, interesting moments, and a brief account of what remains to be implemented for P3.
Rubrics
This assignment assesses implementing a concept-based application, testing and validating software, and technical writing.
Your core user journey must work across concepts, reactions, the front end, and persistent storage, with the necessary access controls. The interface must update without page refreshes and provide appropriate validation and informative error messages for this journey. Additional features and final styling can wait until a later assignment.
Advice
Incremental development plan. It’s up to you what order to do things in, but some general guidance should help. First, make sure that each step is small enough to be easily achieved in a short amount of time so you can assess your progress early on and build confidence. Second, ensure that each step has an outcome that is easily assessed: for example, by including the front-end components that will allow you to see expected results. Third, ensure that earlier steps provide whatever data is needed for later steps, so if a feature requires the database to be populated with particular data, first build the functionality that will make that possible. If something goes wrong and you make a mess, consider undoing the step and taking a smaller step instead. (To make this easy, commit and push after each step.)
Work intentionally and reflectively. Think not only about the artifacts you are producing but also about your process, how you approach problems, how you evaluate solutions, how you overcome their own blindspots and biases, and so on.
Use LLMs with care. Everyone knows LLMs can fail unpredictably and that they can produce poor designs. But the biggest risk of using LLMs is incurring cognitive debt, whereby you offload significant decisions to the agent and lose out on the benefits of working through failures and missteps first-hand. Then it becomes difficult to comprehend the product you're developing, and, worse, your design intuition and problem sense are stifled. Best practice is to task the LLM with carrying out carefully-scoped actions that you can meaningfully understand and evaluate, and to ask the LLM to explain its work. You can also have the LLM build in verification to its own tasks. Read more about our policy on using AI.
Push frequently. Almost every year there is a poor student who delayed pushing their work and then had a laptop or disk failure. Don’t let that happen to you!
Review background documents. The background documents on concept design contain useful advice and reference information on everything from identifying concepts to formatting them correctly and ensuring your designs do not make classic mistakes like failing to separate concerns or ensure concept independence. Remember that you can exploit background materials as prompts to LLMs in order to give yourself a personal assistant equipped with knowledge of concept design. You can do the same with the rubrics, although an LLM's approval does not ensure you will get the same grade from us.
Don't upload API keys. Keep them in secret files in your development environment.
Start early and ask for help. Come to office hours and/or post on Commons. Remember that asking questions helps everyone, and if you’re stuck with something, then other students probably are as well.