Rails-like structure
app/models, app/controllers, app/views, config/routes.js. If you
know Ruby on Rails, you already know where everything goes.

Rails-like structure
app/models, app/controllers, app/views, config/routes.js. If you
know Ruby on Rails, you already know where everything goes.
Server-side rendered React
Pages live in app/views/pages and are rendered by Next.js. Controllers
hand them data with res.render(); the same endpoint answers JSON when
asked for it.
Real ORMs
Mongoose for MongoDB, Sequelize for MySQL, MariaDB, PostgreSQL and MSSQL. A zero-config disk store for prototyping. Models are global, like in Rails.
GraphQL built in
Add a graphql key to a model and its types and resolvers are merged into a
single schema, served by Apollo Server and queryable from res.render().
Hot reload everything
Controllers, models, routes, workers and configuration reload on save. Press
R in the terminal to list the loaded routes.
Generators
henri new, henri generate model, henri generate scaffold. Users get
password hashing, sessions and roles for free.
module.exports = { 'resources tasks': 'tasks', '/': 'tasks#index',};module.exports = { index: async (req, res) => { res.render('/tasks', { data: { tasks: await Task.find() } }); }, create: async (req, res) => { await Task.create(req.body); res.redirect('/'); },};import withHenri from '@usehenri/react';
const Tasks = ({ data }) => ( <ul> {data.tasks.map((task) => ( <li key={task._id}>{task.name}</li> ))} </ul>);
export default withHenri(Tasks);