Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/claudioc/node-htmx-ts-starter-kit
Opinionated, no nonsense starter kit for a simple Express API application
https://github.com/claudioc/node-htmx-ts-starter-kit
express htmx nodejs starter-kit typescript
Last synced: 3 months ago
JSON representation
Opinionated, no nonsense starter kit for a simple Express API application
- Host: GitHub
- URL: https://github.com/claudioc/node-htmx-ts-starter-kit
- Owner: claudioc
- License: mit
- Created: 2023-12-03T18:05:51.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2023-12-25T14:16:24.000Z (about 1 year ago)
- Last Synced: 2023-12-26T15:06:10.108Z (about 1 year ago)
- Topics: express, htmx, nodejs, starter-kit, typescript
- Language: TypeScript
- Homepage:
- Size: 189 KB
- Stars: 5
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Express + TypeScript + HTMX starter kit
## Important
I created a [similar starter kit](https://github.com/claudioc/node-htmx-ts-starter-kit/) using [Fastify](https://fastify.dev/), which nowadays I believe is a better choice over Expressjs, for several reasons. **I will then consider this starter kit "deprecated" and I am not adding any more features or fixes to it**.Motivation: **I am sick of React and frontend building and bundling issues. I just want to build staff**.
The goal of this starter kit is to provide a slightly opinionated but super simple way to get started with a project that has some logic on the backend and some logic on the frontend. A typical use case could be a single page that fetches some information from a third-party API, but you also want to have a small backend where to keep your API keys and maybe a cache to avoid hitting a rate limit on those external API.
The kit contains:
- A server ([Expressjs](https://expressjs.com/) with some middlewares)
- A client (just TypeScript, no frameworks, which you can extend with your logic)
- A demo micro application: reads the current server time and displays it in the browser, auto-refreshing every 30s (or manually)
- Server side error handling
- Linting## Tech stack
- Good ol' [Expressjs](https://expressjs.com/) - but you should consider using [Fastify](https://fastify.dev/) instead
- [EJS](https://ejs.co/) templates
- TypeScript
- [HTMX](https://htmx.org/) for the frontend to speak to the backend
- [Chota](https://jenil.github.io/chota/) framework for the CSS, because it's small and cuteI am not even using `ts-node` because it's not needed for a small project.
### Express middlewares:
- Helmet for security
- Morgan for the logs### Additional tools provided:
- concurrently
- nodemon
- dotenv
- eslint with ts support (extends just the recommended rule set)
- prettier and a bare-bone config
- client's and server's own tsconfig which extends a base one### Bonus
- There is an example of how to write a HTMX extension
- Configurations are all in the package.json### Suggested Visual Studio Code extensions
- EJS language support
- Prettier
- Pretty TypeScript Errors## Project structure
- `server/app.ts` contains just the bare-bone bootstrap code for the server
- `server/lib` contains any additional server module: `bootstrap.ts` is the module setting up Express and its middlewares, `router.ts` contains the routes definition and the error handling, `assets.ts` is used to generate a cache proof name for the assets. There are also some `constants.ts`
- `server/views` contains the view templates in EJS format (HTML + embedded JS). EJS doesn't have the concept of "layouts" or "slots", so in our case, we build each "full page" using partials: header + body + footer. If your app grows in complexity you may want to reconsider this design choice and use a layout-based template system
- `client/app.ts` contains just some code that it's run when the page is loaded in the browser
- `client/lib/tools.ts` is just used as an example of natively including a js module at runtime
- `assets` contains js, css, and vendor files. Keep in mind that the js assets are symlinked from the `dist` directory. All the assets are mounted under the `/a` virtual folderSince this project doesn't use `ts-node`, your app is run directly from the `dist` folder (check the script in package.json to understand how) where the view templates are not copied (because they do not require compilation).
## Try it
Note that it doesn't work on Windows out-of-the-box (makes use of symlinks and bash).
- npm i
- npm run dev
- open http://localhost:3000You also have `npm lint`, `npm build` and of course `npm start` (for production).
## Use it in your project
Some options:
- Download the latest archive from [Github releases](https://github.com/claudioc/node-htmx-ts-starter-kit/releases) or from the "Code" button in the repository main page
- Clone the repo, and then `rm -rf` its `.git` directory (github doesn't support `git archive` and git doesn't have a `export` command like svn does)This project uses ESLint and Prettier: don't forget to install/enable their extension in Visual Studio Code.
To not mess things up, we are not using "eslint-prettier" or similar, but you can try it if you want.
## Deployment
This is on you. I own a small VPS and I run all my projects from there. Ideally, you want to run this process behind a reverse proxy where you also end your TLS connection. I use ngnix and letsencrypt for my tls certificates.
If you have successfully deployed a project inherited from this kit, in some cloud, and you want to share the steps please open a PR!
## What is missing
- Express' body-parser is not installed ([see the doc](https://expressjs.com/en/resources/middleware/body-parser.html)) because I didn't have to POST anything
- no cookie support, because we hate cookie banners
- Assets are not tgz compressed because this should be the job of your reverse proxy
- I use ejs for its simplicity but I don't like not having a type checking in the templates. It should be nice to use JSX, but the risk is to complicate things too much
- Both server and client code reside in the same git repository, and they both share the same package.json and node_modules and that's OK for relatively small project, but you can also decide to move to a monorepo layout using something like [nx](https://nx.dev/) or [TurboRepo](https://turbo.build/) for managing it
- Only the main client js module (app.js) is provided with a cache-bust parameter, whereas any imported module (as in `tools.js` in this project) is not, which means that they only rely to the cache settings of the static middleware. I will leave it up to you to decide if that's enough or if you want to add an additional build step to handle such casesA testing system is also not installed by default, but if you are like me and love [Vitest](https://vitest.dev/), just follow these instructions (for the client, but it should work for the server as well):
- `npm install vitest --save-dev`
- Edit `client/tsconfig.json` and add an `exclude` option for your tests: this is because vitest doesn't use `tsc` for the typescript sources and you should tell `tsc` to not compile and build the tests
- Add a `test` script in your package.json with something like `vitest ./client/**/*.spec.ts`
- Since we are excluding tests from the TS projects, eslint won't be able to find them anymore and we need to put them back somewhere. To do so, you can [follow these instructions](https://typescript-eslint.io/linting/troubleshooting/#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file). I would add a `tsconfig.eslint.json` which extends our base, doesn't emit and includes the test files
- Write your tests away!