Remix seamlessly supports both JavaScript and TypeScript. If you name a file with a .ts
or .tsx
extension, it will treat it as TypeScript (.tsx
is for TypeScript files with JSX in them). But it isn't required. You can write all your files as .js
files if you don't want TypeScript.
The Remix CLI will not perform any type checking. Instead, you'll want to use TypeScript's tsc
CLI yourself. A common solution is to add a typecheck
script to your package.json:
{
"name": "remix-app",
"private": true,
"sideEffects": false,
"scripts": {
"build": "remix vite:build",
"dev": "remix vite:dev",
"lint": "eslint --ignore-path .gitignore .",
"start": "remix-serve ./build/index.js",
"typecheck": "tsc"
},
"dependencies": {
"@remix-run/node": "latest",
"@remix-run/react": "latest",
"@remix-run/serve": "latest",
"isbot": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@remix-run/dev": "latest",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.23.1",
"typescript": "^5.1.6",
"vite": "^5.1.4"
},
"engines": {
"node": ">=18.0.0"
}
}
Then you can run that script as part of continuous integration, alongside your tests.
Remix has TypeScript type definitions built-in as well. For example, the starter templates create a tsconfig.json
file that includes the necessary types for Remix and Vite:
{
"include": [
"**/*.ts",
"**/*.tsx",
"**/.server/**/*.ts",
"**/.server/**/*.tsx",
"**/.client/**/*.ts",
"**/.client/**/*.tsx"
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"types": ["@remix-run/node", "vite/client"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2022",
"strict": true,
"allowJs": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
// Vite takes care of building everything, not tsc.
"noEmit": true
}
}
types
array will depend on which environment you're running your app in. For example, there are different globals available in Cloudflare.