TypeLaunch Turbo is an opinionated, public template repository made to easily bootstrap a TypeScript monorepo for applications and packages with the latest features and best practices.
To use this template
There are multiple edits that should be made to personalize TypeLaunch Turbo. Below is a checklist in order of importance.
- Add a
name
beyond the placeholder inpackage.json
andvite.config.ts
in each public-facing package using Vite as the build tool. Change thename
field in all public facing packages, regardless of build tool. - Add a
SCOPED_REPO_TOKEN
andNPM_TOKEN
to your repo's secrets. This allows GitHub Actions to manage deploying to npm. See this issue for more information, and see this issue as well as this issue for a list of permissions to give to theSCOPED_REPO_TOKEN
. - Replace the placeholder name "John Appleseed" with the project owner's name in each
LICENSE
for all public-facing packages - Replace all instances of the placeholder email "johnnyappleseed@example.com" with the project owner's email address in the
CODE_OF_CONDUCT.md
- Add or customize these fields in each public-facing
package.json
:author
email
description
repository
: provide a link to the GitHub repo the entire project resides inhomepage
: provide a link to one of these resources- Front-facing webpage
- Documentation (we have an app specifically for documentation in the
app
directory for that!) - GitHub repo
bugs.url
: provide a link to your bug trackerkeywords
When opening the project, create a new terminal window and run pnpm run dev
. This will set up Vitest every time the project is saved. Best practice is to stop this terminal when closing the project, though that's not entirely necessary.
When a commit is ready to be made, head to the Version Control pane and stage the files you'd like to commit. Next, look for the circle above the commit field labeled "Conventional Commits", or hit Ctrl/Cmd + Shift + P
to open the Command Palette and find it that way. In the Command Palette, type "Conventional Commits" and find the command with that title.
The Conventional Commits extension will walk you through the steps to making a conventional commit.
When enough commits have been made, make a changeset and push your changes to GitHub! There are two types of commit sets: release, and non-release.
The commit set is a release set if the commit set changes your project's features (i.e. if there are any feat commits). Any other commit set will not require a release and can be considered a non-release set.
To push a release set, run pnpm run change
and note the features you've added, changed, or removed. Commit this and push to a dev
branch. To publish a non-release set, run pnpm run change:empty
and commit and push to the main
branch.
When you're ready to release, take a look at the Pull Request to main that the Changeset GitHub Action has created under your name. Follow the instructions there and only merge the Pull Request when you're comfortable with it. When you do merge, GitHub Actions and Changset will take care of publishing to npm and tagging your release on GitHub.
This project adheres to the following conventions to keep code writing and reviewing easy.
- Conventional Commits
- Semantic Versioning
- ESLint recommended rules
- Prettier recommended rules
This project makes use of some dev dependencies that enforce following the above conventions and overall improve code quality.
- Essentials - TypeScript, a type-safe superset of JavaScript
- Testing and Coverage - Vitest, a fast, batteries-included test runner
- Linting and Formatting
- Version Control and CI/CD
- Changesets for tracking changes and maintaining a changelog
- GitHub Actions for the wider CI/CD pipeline
- TypeScript is provided for type-safety and is intended to be used instead of JavaScript. The base tsconfig included uses strict mode, so the TypeScript compiler will complain about a lot of things. Remember, TypeScript errors are your friend.
- Usage of docstrings is highly encouraged, as it provides an easy way to produce documentation. The docstrings you make allow IDE's like VSCode (my personal favorite) to provide inline documentation and tab completion directly in the editor!
- Use Vitest for test-driven or behavior-driven development. Before working on the project, run
pnpm run dev
to get Vitest going. See the Commands section for more details.
TypeLaunch is an opinionated template. The most important tenets of TypeLaunch are:
- Clutter bad, ❌ intuitive structure good ✅
- Rigidity bad, ❌ easy customization good ✅
- Looseness bad, ❌ constructive strictness good ✅
- Manual bad, ❌ automatic help good ✅
The more granular opinions are described below:
- ESLint is pre-configured in a separate package, and Prettier is pre-configured at the project root. This is where most of the opinions are.
- All recommended Prettier presets are followed
- All recommended ESLint presets are followed, with the exception of two additional rules. They are set to warn and not throw an exception because they are slightly pedantic.
- I've worked on projects where the root directory is a mess of config files with no way to hide them because they all had to be at the root. Therefore, I've tried to hide as much of the config in packages as I can. This also aligns with the second tenet of TypeLaunch.
- In the same spirit, the code of conduct is in the
.github
folder, but can be moved to the project root. - Part of the reason I made this template is to have full control over what tools I used and how I used them. I brought this design philosophy to TypeLaunch as much as I could; if a package is getting in your way, you just need to uninstall it or delete it; the only one that needs some extra config is changesets because that's integrated into the CI build. Otherwise, it's as simple as
pnpm uninstall <package>
and/orrm -rf <directory>
. - TypeLaunch is also dependency-free for a reason: the thing shouldn't get in the way of what your application needs and should only help you if you develop it. Usage of TypeLaunch not contributing to build sizes is also a nice plus.
- Errors are your friend. No seriously. I've configured TypeLaunch to berate the developer with errors, exceptions, and test failures. Errors are also the lifeblood of test-driven development, a practice I'm getting better at following. Adding these errors is meant to make sure the code, docs, and tests are in tip-top shape.
- Turborepo is great. Oftentimes you won't need to worry about messing around with a single package or app because Turborepo handles building, linting, and so on. And Turborepo is ridiculously aggressive about doing as little work as possible; it caches as much as it can so you don't have to manually look through what files changed and which didn't. With TypeLaunch, you still have full control over your builds; run
pnpm uncache
to force Turborepo to recalculate everything. It's like a language server reset for your build/lint system! - Although they're available just in case, you should be careful when running any commands at the project root that spin up a persistent process, like a dev server or a process in watch mode. Turborepo will try to spin up all persistent processes at once, making for a rather cluttered terminal and potentially serving conflicts as dev servers try to use the same host and port to serve web apps. Know what your dev and test commands do before running a dev or test command at the project root!
Utilize these commands in your development pipeline by running pnpm run <command>
(or pnpm <command>
if the command name doesn't conflict with any core pnpm scripts). For convenience, a table for these commands is included here:
Command | Description |
---|---|
start | Run your projects' start command (if it exists) |
dev | Run Vitest tests in watch mode and/or spin up dev servers |
build:dev | Build a dev-friendly/dev-readable build of the project |
build | Build the project, optimized for production |
preview | Run your projects' preview command (if it exists) |
suite | Run a suite of commands to check your code, tailored to development |
suite:ci | Run a suite of commands to check/fix your code, tailored to ci |
test | Run Vitest tests once |
test:watch | Run Vitest tests in watch mode |
cov | Run Vitest tests and provide a coverage report |
cov:watch | Run Vitest tests in watch mode and provide a coverage report |
lint | Lint the project with TSC, ESLint, and Prettier |
mono-lint | Lint the structure of the monorepo using manypkg |
format | Format the project with TSC, ESLint, and Prettier |
mono-fix | Fix the project structure of the monorepo using manypkg |
uncache | Delete all Turborepo caches |
clean | Delete all node_modules directories |
resinstall | Clean the project then reinstall packages |
reset | Clean the project, delete the lockfile, then reinstall packages |
change | Create a changeset |
change:empty | Create a special changeset with no changes noted |
review | Review your changeset changes |
release | Build the project and create or update the changelog |
typelaunch-generate | Recover this directory (and template projects!) |