Yes!
See Contributing to a create-typescript-app Repository.
It'll walk you through the common activities you'll need to contribute to a repository scaffolded with create-typescript-app
.
Yes! After you set up a repository, you can substitute in any tools you'd like.
If you think the tool would be broadly useful to most consumers of this template, feel free to file a feature request to add it in.
Yes! If you want to read the GitHub Actions documentation in detail. Here we'll outline the steps required to migrate a CTA app to a GitHub Action:
-
GitHub Actions store built output on a GitHub branch rather than in a published package on npm. As a consequence we should:
-
delete
.github/workflows/release.yml
and.github/workflows/post-release.yml
. -
update
.github/workflows/build.yml
to ensuredist
is up to date:.github/workflows/build.yml
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: ./.github/actions/prepare - run: pnpm build - name: Compare dist/index.js run: | if [ "$(git diff --ignore-space-at-eol --text dist/index.js | wc -l)" -gt "0" ]; then echo "Detected uncommitted changes after build." echo "You may need to run 'pnpm run build' locally and commit the changes." echo "" echo "See diff below:" echo "" git diff --ignore-space-at-eol --text dist/index.js echo "" # say this again in case the diff is long echo "You may need to run 'pnpm run build' locally and commit the changes." echo "" exit 1 fi name: Build on: pull_request: ~ push: branches: - main permissions: contents: read
-
GitHub Actions run without installing package dependencies. Replace
tsup
withncc
to build source files and dependencies into a single JS file. Deletetsup.config.ts
then execute the following commands:
pnpm remove tsup pnpm add @vercel/ncc -D
- Now we need to update the
build
script in ourpackage.json
:
-"build": "tsup", +"build": "ncc build src/index.ts -o dist --license licenses.txt",
- Our build now emits to the
dist
directory; so we'll want to avoid linting that directory by adding the following to.eslintignore
and our.prettierignore
:
+dist
- Rather than having to remember to compile each time, we'll update our precommit hook in
.husky/precommit
to build for us on each commit:
+pnpm run build +git add dist npx lint-staged
-
-
Create an
action.yml
metadata file.
It's worth reading the GitHub Actions documentation.
First, I'd suggest reading TypeScript Handbook > Modules - Introduction to understand how CommonJS (CJS) and ECMAScript (ESM) came to be.
Then:
-
In
tsup.config.ts
, change the tsupformat
option from["esm"]
to["cjs", "esm"]
-
Add a
package.json
"exports"
entry like:{ "exports": { ".": { "types": { "import": "./lib/index.d.ts", "require": "./lib/index.d.cts" }, "import": "./lib/index.js", "require": "./lib/index.cjs" } } }
That should be it!
To be safe, consider checking with arethetypeswrong:
- Run
pnpm build
- Run
npm pack
- Upload that generated
.tgz
file to arethetypeswrong.github.io
Dual CJS/ESM emit is a stopgap solution while the JavaScript ecosystem migrates towards full ESM support in most-to-all popular user packages.
Most packages newly created with create-typescript-app
should target just ESM by default.
Some packages published with create-typescript
legitimately need dual CJS/ESM output because they're used by frameworks that don't yet fully support ESM.
That's reasonable.
Unless you know a package needs to support a CJS consumer, please strongly consider keeping it ESM-only (the create-typescript-app
default).
ESM-only packages have a smaller footprint by virtue of including fewer files.
Not directly.
You can always copy & paste them in manually, and/or re-run npx create-typescript-app --mode migrate
.
See 🚀 Feature: Add a script to sync the tooling updates from forked template repo #498: it will likely eventually be possible.
eslint-config-prettier
is an ESLint plugin that serves only to turn off all rules that are unnecessary or might conflict with formatters such as Prettier.
None of the ESLint configs enabled by this repository's tooling leave any rules enabled that would need to be disabled.
Using eslint-config-prettier
would be redundant.
The four bases correspond to what have seemed to be the most common user needs of template consumers:
- Minimal: Developers who just want the barest of starting templates.
- They may be very new to TypeScript tooling, or they may have made an informed decision that the additional tooling isn't worth the complexity and/or time investment.
- Tooling in this base is only what would be essential for a small TypeScript package that can be built, formatted, linted, and released.
- Common: The common case of users who want the minimal tooling along with common repository management.
- Tooling added in this base should be essential for a TypeScript repository that additionally automates useful GitHub tasks: contributor recognition, release management, and testing.
- Everything: Power users (including this repository) who want as much of the latest and greatest safety checks and standardization as possible.
Note that users can always customize exactly with portions are kept in with --base
prompt
.
The following pieces of this template's tooling don't have options to be removed:
- Linting with ESLint and
pnpm run lint
- GitHub repository metadata such as the code of conduct and issue templates
- Prettier and
pnpm run format
- tsup and
pnpm run build
- TypeScript and
pnpm run tsc
If you have a strong desire to add an --exclude-*
flag for any of them, please do file a feature request.
This repository is meant to serve as a starter that includes all the general tooling a modern TypeScript/Node repository could possibly need. Each of the included tools exists for a good reason and provides real value.
If you don't want to use any particular tool, you can always remove it manually.
Glad you asked!
These are the projects used across many parts of create-typescript-app
:
- Chalk: Makes it easier to print colored characters in the terminal.
- Clack: Provides interactive terminal prompts and loading spinners.
- execa: Makes it easier to run child processes.
- Octokit:
- tsx: Quickly runs TypeScript files with ESBuild.
- Zod: TypeScript-first schema validation with static type inference.
This repository template configures "useTabs": true
in the root-level .prettierrc.json
.
It does so because tabs have been phrased by the community as generally better for accessibility:
Note that those points on tabs over spaces have generally been made by accessibility-experienced individuals rather than accessibility-focused organizations. If you know of any accessibility organization that's published more formal recommendations or research, please do file an issue here for this FAQ entry to be updated.
You can adjust the tab size that GitHub uses to display files from your account settings page (the default is 8 spaces).
If you really want spaces in your project you can always remove the "useTabs": true
.
The --bin
option allows you to create a package.json
bin value to include for npx-style running.
An example of this would be "./bin/index.js"
.
You'll need to create the folders and files that bin
references.
If you'd like an example of what that looks like, take a look at the CTA source code!