Skip to content

The Nx Plugin for Remix contains executors, generators, and utilities for managing Remix applications and libraries within an Nx workspace. It provides:

  • Integration with libraries such as Storybook, Jest, Vitest, Playwright and Cypress.
  • Generators to help scaffold code quickly, including:
    • Libraries, both internal to your codebase and publishable to npm
    • Routes
    • Loaders
    • Actions
    • Meta
  • Utilities for automatic workspace refactoring.

In any Nx workspace, you can install @nx/remix by running the following command:

nx add @nx/remix

This will install the correct version of @nx/remix.

The @nx/remix plugin will create a task for any project that has a Remix configuration file present. Any of the following files will be recognized as a Remix configuration file:

  • remix.config.js
  • remix.config.mjs
  • remix.config.cjs

To view inferred tasks for a project, open the project details view in Nx Console or run nx show project my-project --web in the command line.

The @nx/remix/plugin is configured in the plugins array in nx.json.

nx.json
{
"plugins": [
{
"plugin": "@nx/remix/plugin",
"options": {
"buildTargetName": "build",
"devTargetName": "dev",
"startTargetName": "start",
"typecheckTargetName": "typecheck"
}
}
]
}

The buildTargetName, devTargetName, startTargetName and typecheckTargetName options control the names of the inferred Remix tasks. The default names are build, dev, start and typecheck.

nx g @nx/remix:app apps/myapp
NX Generating @nx/remix:application
✔ What unit test runner should be used? · vitest
✔ Which E2E test runner would you like to use? · playwright
UPDATE package.json
UPDATE nx.json
CREATE apps/myapp/project.json
CREATE apps/myapp/README.md
CREATE apps/myapp/app/nx-welcome.tsx
CREATE apps/myapp/app/root.tsx
CREATE apps/myapp/app/routes/_index.tsx
CREATE apps/myapp/public/favicon.ico
CREATE apps/myapp/remix.config.js
CREATE apps/myapp/remix.env.d.ts
CREATE apps/myapp/tests/routes/_index.spec.tsx
CREATE apps/myapp/tsconfig.app.json
CREATE apps/myapp/tsconfig.json
CREATE apps/myapp/.gitignore
CREATE apps/myapp/package.json
CREATE apps/myapp/tsconfig.spec.json
CREATE apps/myapp/vitest.config.ts
CREATE apps/myapp/test-setup.ts
CREATE apps/myapp/.eslintrc.json
CREATE apps/myapp/.eslintignore
CREATE apps/myapp-e2e/project.json
CREATE apps/myapp-e2e/src/example.spec.ts
CREATE apps/myapp-e2e/playwright.config.ts
CREATE apps/myapp-e2e/tsconfig.json
CREATE apps/myapp-e2e/.eslintrc.json
  1. To build your application run:
nx build myapp
> nx run myapp:build
Building Remix app in production mode...
Built in 857ms
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX Successfully ran target build for project myapp (3s)
  1. To serve your application for use during development run:
nx dev myapp
> nx run myapp:dev
> remix dev --manual
💿 remix dev
info building...
info built (388ms)
[remix-serve] http://localhost:3000 (http://192.168.0.12:3000)
  1. To test the application using vitest run:
nx test myapp
> nx run myapp:test
> vitest
RUN v1.6.0 /Users/columferry/dev/nrwl/issues/gh_issues/nx26943/apps/myapp
✓ tests/routes/_index.spec.tsx (1)
✓ renders loader data
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 13:22:54
Duration 533ms (transform 47ms, setup 68ms, collect 123ms, tests 36ms, environment 204ms, prepare 35ms)
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
NX Successfully ran target test for project myapp (950ms)

When developing your application, it often makes sense to split your codebase into smaller more focused libraries.

To generate a library to use in your Remix application run:

nx g @nx/remix:lib libs/login
NX Generating @nx/remix:library
✔ What test runner should be used? · vitest
UPDATE nx.json
UPDATE package.json
CREATE babel.config.json
CREATE libs/login/project.json
CREATE libs/login/.eslintrc.json
CREATE libs/login/README.md
CREATE libs/login/src/index.ts
CREATE libs/login/tsconfig.lib.json
CREATE libs/login/tsconfig.json
CREATE libs/login/vite.config.ts
CREATE libs/login/tsconfig.spec.json
CREATE libs/login/src/lib/login.module.css
CREATE libs/login/src/lib/login.spec.tsx
CREATE libs/login/src/lib/login.tsx
UPDATE tsconfig.base.json
CREATE libs/login/src/test-setup.ts
CREATE libs/login/src/server.ts

You can then use the library by importing one of the exports into your application:

apps/myapp/app/routes/index.tsx

apps/myapp/app/routes/index.tsx
import { Login } from '@acme/login';
export default function Index() {
return (
<div>
<Login />
</div>
);
}

You can also run test on your library:

nx test login

To generate a route for your application:

nx g @nx/remix:route apps/myapp/app/routes/admin
NX Generating @nx/remix:route
CREATE apps/myapp/app/routes/admin.tsx
CREATE apps/myapp/app/styles/admin.css

To use a Route Loader where the logic lives in your library, follow the steps below.

  1. Generate a loader for your route:
nx g @nx/remix:loader apps/myapp/app/routes/admin.tsx
NX Generating @nx/remix:loader
UPDATE apps/myapp/app/routes/admin.tsx
  1. Add a new file in your login lib

libs/login/src/lib/admin/admin.loader.ts

libs/login/src/lib/admin/admin.loader.ts
import { json, LoaderFunctionArgs } from '@remix-run/node';
export const adminLoader = async ({ request }: LoaderFunctionArgs) => {
return json({
message: 'Hello, world!',
});
};

Export the function from the libs/login/src/server.ts file:

libs/login/src/server.ts
export * from './lib/admin/admin.loader';
  1. Use the loader in your apps/myapp/app/routes/admin.tsx

Replace the default loader code:

apps/myapp/app/routes/admin.tsx
export const loader = async ({ request }: LoaderFunctionArgs) => {
return json({
message: 'Hello, world!',
});
};

with

import { adminLoader } from '@acme/login/server';
export const loader = adminLoader;

You can see an example of an Nx Workspace using Remix by clicking below.