Home

Awesome

Best practices starter

<br/>

Generate a Node.js app that is packed with best practices AND simplicity in mind. Based off our repo Node.js best practices (96,100 stars)

<br />

Twitter Twitter | Site Documentation site

<br/>

A One Paragraph Overview

Although Node.js has great frameworks 💚, they were never meant to be dev & production ready immediately (e.g., no architecture layers, DB schemas, docker file, etc etc). Practica.js aims to bridge the gap. Based on your preferred framework, we generate example code that demonstrates a full Microservice flow, from API to DB, that is packed with good practices. For example, we include a battle-tested error handler, sanitized API response, hardened dockerfile, thoughtful 3-tier folder structure, great testing templates with DB, and more. This saves a great deal of time and can prevent painful mistakes. All decisions made are neatly and thoughtfully documented. We strive to keep things as simple and standard as possible and base our work on the popular guide: Node.js Best Practices

1 min video 👇, ensure audio is activated

https://user-images.githubusercontent.com/8571500/170464232-43355e43-98cf-4069-b9fc-6bc303a39efc.mp4

<br/>

Table of Contents

<br />

Super-Quick Setup

<br />

Run Practica.js from the Command Line

Run practica CLI and generate our default app (you can customize it using different flags):

npx @practica/create-node-app immediate --install-dependencies

✨ And you're done! That's it, the code's all been generated. Our default setup includes Fastify for the web layer, Sequelize for the data access and PostgreSQL

Prefer express and Prisma? Just pass the right flags to the CLI:

npx @practica/create-node-app immediate --install-dependencies --web-framework=express --orm=prisma

Prefer other DB? We use standard ORMs, read its docs and switch DB. This is your code, do whatever you like

<br />

Start the Project

cd {your chosen folder name}
npm install

Then choose whether to start the app:

npm run

or run the tests:

npm test

Pretty straightforward, right?

You just got a Node.js Monorepo solution with one example component/Microservice and multiple libraries. Based on this hardened solution you can build a robust application. The example component/Microservice is located under: {your chosen folder name}/services/order-service. This is where you'll find the API and a good spot to start your journey from

<br />

Next Steps

<br />

Our Philosophies and Unique Values

1. Best Practices on top of known Node.js frameworks

We don't re-invent the wheel. Rather, we use your favorite framework and empower it with structure and real examples. With a single command you can get an Express/Fastify-based codebase with many thoughtful best practices inside

Built on top of known frameworks

2. Simplicity, how Node.js was intended

Keeping it simple, flat, and based on native Node/JS capabilities is part of this project's DNA. We believe that too many abstractions, high-complexity or fancy language features can quickly become a stumbling block for the team

To name a few examples, our code flow is flat with almost no level of indirection, no DI - it's just simple functions calling other functions. Although using TypeScript, almost no features are being used besides types, for modularization we simply use... Node.js modules

Simplicity!

3. Supports many technologies and frameworks

Good Practices and Simplicity is the name of the game with Practica. There is no need to narrow our code to a specific framework or database. We aim to support the popular Node.js frameworks and data access approaches

Built on top of known frameworks

<br />

Practices and Features

We apply dozens of practices and optimizations. You can opt in or out for most of these features using option flags on our CLI. The following table lists just a few examples out of the full list of features we provide.

FeatureExplanationFlagDocs
Monorepo setupGenerates two components (e.g., Microservices) in a single repository with interactions between the two--mr, --monorepoDocs here
Output escaping and sanitizingClean-out outgoing responses from potential HTML security risks like XSS--oe, --output-escapeDocs here
Integration (component) testingGenerates full-blown component/integration tests setup including DB--t, --testsDocs here
Unique request ID (Correlation ID)Generates module that creates a unique correlation/request ID for every incoming request. This is available for any other object during the request life-span. Internally it uses Node's built-in AsyncLocalStorage--coi, --correlation-idDocs here
DockerfileGenerates dockerfile that embodies >20 best practices--df, --docker-fileDocs here
Strong-schema configurationA configuration module that dynamically load run-time configuration keys and includes a strong schema so it can fail fastBuilt-in with basic appDocs here

📗 See our full list of features here

<br />

The People Behind Practica.js

Steering Committee

Practica is a community-driven open-source project. It's being led voluntarily by engineers from many different companies. These companies are just a few who encourage their engineers to contribute and keep this project moving. 💚

Autodesk

A Nasdaq 100 company, a world leader in design software

Cox2m

Leader IoT provider, part of 'Cox Communication', the 3rd largest cable company in the US

Core Team

<table width="700px"> <tr> <td align="center"><img src="./static/images/yoni.jpeg" width="300px" alt=""/><br /><h3>Yoni Goldberg</h3><br/>Independent Node.js consultant<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> <td align="center"><img src="./static/images/michael1.jpg" width="300px" alt=""/><br /><h3>Michael Solomon</h3><br/>Node.js lead<br/><a href="https://twitter.com/JMichaelShlomo"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> </td> </tr> <tr> <td align="center"><img src="./static/images/raz.jpeg" width="300px" alt=""/><br /><h3>Raz Luvaton</h3><br/>Node.js developer<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> <td align="center"><img src="./static/images/daniel.jpeg" width="300px" alt=""/><br /><h3>Daniel Gluskin</h3><br/>Node.js lead<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> </tr> <tr> <td align="center"><img src="./static/images/ariel.jpeg" width="300px" alt=""/><br /><h3>Ariel Steiner</h3><br/>Node.js developer<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> <td align="center"><img src="./static/images/tomer.jpeg" width="300px" alt=""/><br /><h3>Tomer Kohane</h3><br/>Frontend geek<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> </tr> <tr> <td align="center"><img src="./static/images/dan.png" width="300px" alt=""/><br /><h3>Dan Goldberg</h3><br/>Node.js lead<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> <td align="center"><img src="./static/images/ron.jpeg" width="300px" alt=""/><br /><h3>Ron Dahan</h3><br/>Node.js expert<br/><a href="https://twitter.com/goldbergyoni"><img src="./static/images/twitter-symbol.png" width="16" height="16"></img></a> <a href="https://goldbergyoni.com"><img src="./static/images/site-symbol.png" width="16" height="16"></img></a> </td> </tr> </table> <br />

Partners

These companies are keen for continuous improvement and their engineers to have been known to contribute during work hours.

Minta

Our Amazing Contributors 💚

A million thanks to these great people who have contributed code to our project:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tbody> <tr> <td align="center" valign="top" width="25%"><a href="https://www.clarkio.com"><img src="https://avatars.githubusercontent.com/u/6265396?v=4?s=200" width="200px;" alt="Brian Clark"/><br /><sub><b>Brian Clark</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=clarkio" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/rluvaton"><img src="https://avatars.githubusercontent.com/u/16746759?v=4?s=200" width="200px;" alt="Raz Luvaton"/><br /><sub><b>Raz Luvaton</b></sub></a><br /><a href="#content-rluvaton" title="Content">🖋</a> <a href="https://github.com/practicajs/practica/commits?author=rluvaton" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/mikicho"><img src="https://avatars.githubusercontent.com/u/11459632?v=4?s=200" width="200px;" alt="Michael Solomon"/><br /><sub><b>Michael Solomon</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=mikicho" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/itainoam"><img src="https://avatars.githubusercontent.com/u/12605830?v=4?s=200" width="200px;" alt="itainoam"/><br /><sub><b>itainoam</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=itainoam" title="Code">💻</a> <a href="#projectManagement-itainoam" title="Project Management">📆</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/shanizlo"><img src="https://avatars.githubusercontent.com/u/39856071?v=4?s=200" width="200px;" alt="shanizlo"/><br /><sub><b>shanizlo</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=shanizlo" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/RonDaha"><img src="https://avatars.githubusercontent.com/u/30000700?v=4?s=200" width="200px;" alt="Ron Dahan"/><br /><sub><b>Ron Dahan</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=RonDaha" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/alonkishoni"><img src="https://avatars.githubusercontent.com/u/49868301?v=4?s=200" width="200px;" alt="AlonK"/><br /><sub><b>AlonK</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=alonkishoni" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://twitter.com/joseluah53"><img src="https://avatars.githubusercontent.com/u/11966345?v=4?s=200" width="200px;" alt="Jose Luis Alvarez Herrera"/><br /><sub><b>Jose Luis Alvarez Herrera</b></sub></a><br /><a href="#content-jalvar53" title="Content">🖋</a> <a href="https://github.com/practicajs/practica/commits?author=jalvar53" title="Code">💻</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/reinaldo-calderon-team"><img src="https://avatars.githubusercontent.com/u/60945397?v=4?s=200" width="200px;" alt="reinaldo-calderon-team"/><br /><sub><b>reinaldo-calderon-team</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=reinaldo-calderon-team" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/KarelVerschraegen"><img src="https://avatars.githubusercontent.com/u/11301291?v=4?s=200" width="200px;" alt="KarelVerschraegen"/><br /><sub><b>KarelVerschraegen</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=KarelVerschraegen" title="Documentation">📖</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/danm"><img src="https://avatars.githubusercontent.com/u/6394846?v=4?s=200" width="200px;" alt="Daniel Morrison"/><br /><sub><b>Daniel Morrison</b></sub></a><br /><a href="#content-danm" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/seanlowe"><img src="https://avatars.githubusercontent.com/u/35589586?v=4?s=200" width="200px;" alt="Sean Lowe"/><br /><sub><b>Sean Lowe</b></sub></a><br /><a href="#example-seanlowe" title="Examples">💡</a> <a href="#content-seanlowe" title="Content">🖋</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/idobetesh"><img src="https://avatars.githubusercontent.com/u/58806763?v=4?s=200" width="200px;" alt="idobetesh"/><br /><sub><b>idobetesh</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=idobetesh" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/alejaacosta17"><img src="https://avatars.githubusercontent.com/u/89855093?v=4?s=200" width="200px;" alt="Alejandra Acosta"/><br /><sub><b>Alejandra Acosta</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=alejaacosta17" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/adandanielteamint"><img src="https://avatars.githubusercontent.com/u/104020188?v=4?s=200" width="200px;" alt="adandanielteamint"/><br /><sub><b>adandanielteamint</b></sub></a><br /><a href="#content-adandanielteamint" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/rashad612"><img src="https://avatars.githubusercontent.com/u/251991?v=4?s=200" width="200px;" alt="Rashad Majali"/><br /><sub><b>Rashad Majali</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=rashad612" title="Code">💻</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/yohai-zv"><img src="https://avatars.githubusercontent.com/u/57675671?v=4?s=200" width="200px;" alt="yohai zvuloon"/><br /><sub><b>yohai zvuloon</b></sub></a><br /><a href="#content-yohai-zv" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://yonatankra.com"><img src="https://avatars.githubusercontent.com/u/6459899?v=4?s=200" width="200px;" alt="Yonatan Kra"/><br /><sub><b>Yonatan Kra</b></sub></a><br /><a href="#content-YonatanKra" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/yoni-rapoport"><img src="https://avatars.githubusercontent.com/u/16318253?v=4?s=200" width="200px;" alt="Yoni Rapoport"/><br /><sub><b>Yoni Rapoport</b></sub></a><br /><a href="#content-yoni-rapoport" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/perilevy"><img src="https://avatars.githubusercontent.com/u/29686391?v=4?s=200" width="200px;" alt="perilevy"/><br /><sub><b>perilevy</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=perilevy" title="Code">💻</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/ToMer-K"><img src="https://avatars.githubusercontent.com/u/18401157?v=4?s=200" width="200px;" alt="ToMer-K"/><br /><sub><b>ToMer-K</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=ToMer-K" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/henarbel"><img src="https://avatars.githubusercontent.com/u/87380400?v=4?s=200" width="200px;" alt="hen arbel"/><br /><sub><b>hen arbel</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=henarbel" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/mojcaostir"><img src="https://avatars.githubusercontent.com/u/34694446?v=4?s=200" width="200px;" alt="Mojca Ostir"/><br /><sub><b>Mojca Ostir</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=mojcaostir" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/evbambly"><img src="https://avatars.githubusercontent.com/u/45696895?v=4?s=200" width="200px;" alt="evbambly"/><br /><sub><b>evbambly</b></sub></a><br /><a href="#content-evbambly" title="Content">🖋</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/AmirAdarGit"><img src="https://avatars.githubusercontent.com/u/44618095?v=4?s=200" width="200px;" alt="Amir Adar"/><br /><sub><b>Amir Adar</b></sub></a><br /><a href="#content-AmirAdarGit" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://vaucouleur.com"><img src="https://avatars.githubusercontent.com/u/12293?v=4?s=200" width="200px;" alt="Sebastien Vaucouleur"/><br /><sub><b>Sebastien Vaucouleur</b></sub></a><br /><a href="#content-vaucouleur" title="Content">🖋</a></td> <td align="center" valign="top" width="25%"><a href="https://hkdobrev.com"><img src="https://avatars.githubusercontent.com/u/506129?v=4?s=200" width="200px;" alt="Harry Dobrev"/><br /><sub><b>Harry Dobrev</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=hkdobrev" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://skippednote.dev"><img src="https://avatars.githubusercontent.com/u/2114712?v=4?s=200" width="200px;" alt="Bassam Ismail"/><br /><sub><b>Bassam Ismail</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=skippednote" title="Documentation">📖</a></td> </tr> <tr> <td align="center" valign="top" width="25%"><a href="https://github.com/marcosmol204"><img src="https://avatars.githubusercontent.com/u/53741892?v=4?s=200" width="200px;" alt="Marcos Molina"/><br /><sub><b>Marcos Molina</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=marcosmol204" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/isenkasa"><img src="https://avatars.githubusercontent.com/u/65561129?v=4?s=200" width="200px;" alt="Isen Kasa"/><br /><sub><b>Isen Kasa</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=isenkasa" title="Code">💻</a></td> <td align="center" valign="top" width="25%"><a href="https://github.com/vishal-sharma-369"><img src="https://avatars.githubusercontent.com/u/106011641?v=4?s=200" width="200px;" alt="Vishal Sharma"/><br /><sub><b>Vishal Sharma</b></sub></a><br /><a href="https://github.com/practicajs/practica/commits?author=vishal-sharma-369" title="Code">💻</a></td> </tr> </tbody> </table> <!-- markdownlint-restore --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END -->