Insane productivity for NodeJS apps with the CHARM stack
Tags: javascript, react, meteor, node
Published: 2022-10-27 13:28:16

It is a consensus around the JavaScript community that MeteorJS is an awesome tool for productivity in the backend. In this blog post, I will introduce and evangelize this stack that focuses on making your Developer Experience as smooth as possible.
To follow along, you can check the [GitHub repo](https://github.com/Grubba27/simpletasks) with the template. There you can also read about the tech decisions.

## What and why this stack?
The main goal is to make development as quick and efficient as possible. To achieve this have selected these technologies:
- [Meteor](https://www.meteor.com/) - Fullstack framework focused on productivity that uses RPCs and Sockets for reactivity.
- [React](https://reactjs.org/) - Minimal UI Library for building on the web.
- [Chakra UI](https://chakra-ui.com/) - React library focused on simplicity and productivity.
- [Formik](https://formik.org/) - Most used Form lib for React focuses on making easier-to-write forms
- [MongoDB](https://www.mongodb.com/) - NoSQL and really powerful for prototyping and creating ready-to-use apps out of the box.
- [Meteor Cloud](https://www.meteor.com/cloud) - Cloud provider that makes Deploying a Server with, Database included painless.

## How is the project structured?
Before explaining, this template is inspired by the works of Alex Kondov: [Tao of Node](https://alexkondov.com/tao-of-node/) and [Tao of React](https://alexkondov.com/tao-of-react/).

Most Meteor apps are built similarly to a monorepo with their divisions for back end and front end declared respectively in `ui` and `api` folders. You can have a common folder to share code between frontend and backend. For example, if you use TypeScript, you can share types in your codebase.

A good practice that needs to be pointed out is organizing the folders by feature so that when we think about that specific domain feature, we only need to go to that feature folder. Everything exclusive to that feature should be there. We usually place things in the common directory when we have items that will be used in many places.

![Project Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hj0c2nue32637qc4lwx4.png)

## Backend decisions
In this template, we have chosen to use Mongo, shipped out of the box with MeteorJS, and added some packages to make it even more productive. That being said, we decided to use `simple-schema` and `percolate:migrations`, The first one is for validating schemas in run-time, and the second is for creating database migrations.

## Database Migrations
> Questions on how to structure your migrations?
> Use `api/db/migration.js` as your reference.

This is the kind of feature that sometimes comes in handy. Whenever the server starts, it runs the code below that is located in `api/main.js`:

```javascript
import { Meteor } from 'meteor/meteor';
import { Migrations } from 'meteor/percolate:migrations';
import './db/migrations';
import './tasks/tasks.methods';
import './tasks/tasks.publications';
/**
 * This is the server-side entry point
 */
Meteor.startup(() => {
  Migrations.migrateTo('latest');
});
```

It gathers all migrations that have not been applied and applies them. A great use for migrations is when you have a change in your database, and you could need everyone to have at least the default data. For more details, you can check the [package docs](https://github.com/percolatestudio/meteor-migrations).

## Schemas
Schemas are a manner to be sure that the data that comes from the front end is the way we expect it to be and also it is sanitized. We have decided to use `simpl-schema` and attach it to our collection, as shown in `api/tasks/tasks.collection.js`. Doing this allows all data that goes to our Database to be validated and follow the structure we defined. You can see how a Task is structured, and by having that schema, we can start doing methods and publications.

Don’t forget to check [simpl-schema docs](https://www.npmjs.com/package/simpl-schema) in case of doubts on how to use it.

## Server Connection
Following the idea of having a folder for each feature and if it connects to the front end, we need to provide a way to connect. Meteor works similarly to [tRPC](https://trpc.io/) and [Blitz.js](https://blitzjs.com/). This model has server functions that get called through a Remote Procedure Call (RPC). In this template, calls that are related to tasks are in the `api/tasks/tasks.methods.js` folder.

```javascript
/**
 * Remove a task.
 * @param {{ taskId: String }}
 * @throws Will throw an error if user is not logged in or is not the task owner.
 */
export const removeTask = ({ taskId }) => {
  checkTaskOwner({ taskId });
  TasksCollection.remove(taskId);
};
...
Meteor.methods({
  insertTask,
  removeTask,
  toggleTaskDone,
});
```

So in order to call this server method, we need to do a call for its name. It would look like this:

```javascript
onDelete={taskId => Meteor.call('removeTask', { taskId })}
```

This sample comes from `ui/tasks/TaskItems.jsx`.

## Subscriptions
MeteorJS supports subscriptions out of the box that can be seen in `api/tasks/tasks.publications.js` these publications are called in a similar way to RPC methods, but their values are reactive. For more details on how to deal and think in reactive programming, [Andre Stalz](https://staltz.com/) has this [gist introducing Reactive Programming](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754), and [Kris Kowal](https://github.com/kriskowal) has [this Repo](https://github.com/kriskowal/gtor) that discusses the theory of reactivity in-depth.

> For using subscripiton as you can see in our docs, is similar to using methods. In React we use meteor/react-meteor-data for having a react-way of calling those methods
> For a good example of Subscriptions, you can look in `ui/tasks/TaskPage.jsx`.

## Frontend decisions
![Task Form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kyiv43hkr3qil8fr3na.png)

## React with Meteor is ❤
As for our frontend framework, we have chosen React for its productive ecosystem and simplicity. Meteor has a package for querying data using hooks, which makes you think about only bringing solutions to life. For more information, you can check [react-meteor-data repo](https://github.com/meteor/react-packages/tree/master/packages/react-meteor-data#react-meteor-data) for more details on using the best of them.

## Forms
As one of the key parts of the front end, we have chosen a library to help us deal with this piece. Formik is one of the most expressive ways of writing forms in React, a good template for creating this kind of form is located in `ui/tasks/TaskForm.jsx` it is also integrated with Meteor by its call method. Want to know more and how to create many things with Formik? [Their documentation](https://formik.org/docs/overview).

## The productivity core: Chakra-UI

![Sign-in light](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k9246o391ysirn560n6s.png)

![Sign-in dark](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5x0hzfdbnlrs00k80sy6.png)

For our UI components, we have chosen Chakra UI because of its productivity that matches what Meteor does in the backend creating a lovely flow with an outstanding Developer Experience. We have included Dark and Light modes. It can be seen in those configs in `ui/App.jsx`. You can see Chakra-UI’s full component list on [their website](https://chakra-ui.com/getting-started).

## Did We Pique Your Interest?
After all this tech explanation about why we have chosen this wonderful stack, we encourage you to try it! You can [click here](https://github.com/Grubba27/simpletasks) to see the template. If there are any questions about this template, you can reach out to us on [meteor/meteor](https://github.com/meteor/meteor). Don’t forget to star us on GitHub as well!