Build LMS platform from scratch. Part 2 — define tech stack.
Knowing the business requirements for our Learning Management System (LMS) from the previous article, we can start choosing our tech stack. If you haven’t looked at the previous one I strongly recommend to do so.
What did I choose?
I remember a good thought from Robert Martin in Clean Code — you should delay most technical decisions as long as possible. The longer you keep things flexible, the easier it is to adapt when new requirements pop up.
I don’t want to overcomplicate my app. Nonetheless, I want to have the most comfortable solutions that will help me along the way.
In this series:
Selected tech stack
- Backend: Elixir + Phoenix Framework
I chose Elixir because it’s lightweight, fast, and lets me focus on business logic instead of firefighting strange bugs. It’s built for scalability and can provide a fault-tolerant system in the long run. Also, I have a goal to get to know this language better, so I’ll take it.
Phoenix framework will provide a web server along with test tools.
- Database: Postgres SQL
Since LMS has a well-defined, structured schema, choosing an SQL database just makes sense. Another big reason for going with SQL is the support for ACID (Atomicity, Consistency, Isolation, Durability) properties which are crucial for such systems.
- Frontend: React + Typescript + Remix Framework
Since the LMS is expected to be quite complex, it will require strong support for SEO, SSR, and nested layouts. After evaluating different options, I’ve decided to go with React + Remix.
The development speed is way faster rather than in backend UI frameworks because Remix makes it super easy to handle nested routing, data fetching, and error boundaries, which will be a huge help as the app grows.
The downside? I’ll need to set up an API for frontend-backend communication. But that’s a tradeoff I’m willing to make for the flexibility and speed Remix brings me.
- Client-server communication: RESTful style, REST API
I was thinking about what to choose here, and I settled on the REST API. It will be more than enough for all my tasks and is generally pretty easy to use. I don’t want to complicate things with something like RPC, or GraphQL, as it would slow down the MVP development without really offering any advantages at this stage.
- Live communication: Server-sent events (SSE)
If I need to send messages from the server, I’ll use SSE. I don’t see any reason to use WebSockets just yet.
- CI/CD: Docker, Github Actions, AWS ECS, AWS RDS, AWS ECR
I’m using Docker for image build, GitHub Actions for pipelines, and AWS ECS for containers. Data is handled by AWS RDS, and AWS ECR stores the Docker images.
- Storage: AWS S3
It’s reliable, easy to integrate, and since all my infrastructure is on AWS, it fits perfectly.
Conclusion
Knowing our tech stack and business requirements, we can move forward and design the entities for the database. That’s what we’ll do in the next article.