<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: jonl</title>
    <description>The latest articles on DEV Community by jonl (@jonl).</description>
    <link>https://dev.to/jonl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3192344%2F382a53b3-51a4-4e6a-b110-f7192a372195.png</url>
      <title>DEV Community: jonl</title>
      <link>https://dev.to/jonl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonl"/>
    <language>en</language>
    <item>
      <title>Build a Simple Monolith Backend with Node.js and TypeScript</title>
      <dc:creator>jonl</dc:creator>
      <pubDate>Wed, 21 May 2025 16:51:42 +0000</pubDate>
      <link>https://dev.to/jonl/build-a-simple-monolith-backend-with-nodejs-and-typescript-46ld</link>
      <guid>https://dev.to/jonl/build-a-simple-monolith-backend-with-nodejs-and-typescript-46ld</guid>
      <description>&lt;p&gt;A clear guide to setting up a monolithic backend using Express, TypeScript, Yarn, and modern tooling.&lt;br&gt;
Build a Simple Monolith Backend with Node.js and TypeScript&lt;/p&gt;

&lt;p&gt;Many developers jump straight into microservices, even when it's not needed. For small teams or early-stage products, a monolith is often the better choice.&lt;/p&gt;

&lt;p&gt;This post will walk you through building a &lt;strong&gt;monolith backend&lt;/strong&gt; that is easy to understand, maintain, and ready for production. We use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js + TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Express&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Yarn&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ESLint + Prettier&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jest for testing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Husky + Commitlint&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions for CI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Why Monolith?
&lt;/h2&gt;

&lt;p&gt;Here are a few reasons to start with a monolith:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simpler to build and debug&lt;/strong&gt; — everything is in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster to develop&lt;/strong&gt; — no need to set up multiple repos or services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier to refactor&lt;/strong&gt; later into microservices when needed.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Tools We Use
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Express.js&lt;/td&gt;
&lt;td&gt;Handles routes and middleware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;Adds type safety and better tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESLint + Prettier&lt;/td&gt;
&lt;td&gt;Makes your code clean and consistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jest&lt;/td&gt;
&lt;td&gt;For running tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Husky + Commitlint&lt;/td&gt;
&lt;td&gt;Ensures good commits and quality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Yarn&lt;/td&gt;
&lt;td&gt;Dependency manager&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Folder Structure
&lt;/h2&gt;

&lt;p&gt;Here’s how the project is organized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── app.ts           # Setup express and middleware
├── server.ts        # Start the server
├── routes/          # Define routes
├── controllers/     # Request handlers
├── services/        # Business logic
├── middleware/      # Error &amp;amp; security middleware
├── config/          # Environment setup
└── utils/           # Helper functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Setup in 5 Steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/jonilabss/boelpart-nodejs-monolith-ts.git
&lt;span class="nb"&gt;cd &lt;/span&gt;boelpart-nodejs-monolith-ts
yarn &lt;span class="nb"&gt;install
&lt;/span&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your server will run at &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Tests
&lt;/h2&gt;

&lt;p&gt;We use Jest for testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;test
&lt;/span&gt;yarn &lt;span class="nb"&gt;test&lt;/span&gt;:coverage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to keep test coverage as close to 100% as possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Git &amp;amp; CI Workflow
&lt;/h2&gt;

&lt;p&gt;We use &lt;strong&gt;Husky&lt;/strong&gt;, &lt;strong&gt;Lint-Staged&lt;/strong&gt;, and &lt;strong&gt;Commitlint&lt;/strong&gt; to make sure every commit is clean.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only allow commits that follow &lt;a href="https://www.conventionalcommits.org/" rel="noopener noreferrer"&gt;Conventional Commits&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lint and test before commit and push&lt;/li&gt;
&lt;li&gt;CI with GitHub Actions runs on every pull request&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CI config is in &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;You can deploy this project on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Railway, Render, Vercel (for serverless)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;PM2 (on your own VPS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build and start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn build
yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Monoliths are still useful, especially if you use the right tools. This setup gives you a strong foundation and makes it easier to move to microservices in the future if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/" rel="noopener noreferrer"&gt;TypeScript Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commitlint.js.org/" rel="noopener noreferrer"&gt;Commitlint Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want examples like login features, global error handlers, or DB integration (MongoDB, PostgreSQL)?&lt;br&gt;
Check out the &lt;a href="https://github.com/jonilabss/boelpart-nodejs-monolith-ts.git" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
