DEV Community

Cover image for Remix in Turbo & NX Workspaces (Monorepo Comparison)
bronifty
bronifty

Posted on

Remix in Turbo & NX Workspaces (Monorepo Comparison)

My productivity was higher with Turbo, but there is a caveat: you currently need to use a special library to export modules for Remix since it's not natively supported in these monorepos. Nx had more explicit configuration.

Video Demos

Turbo

npx create-turbo@latest ./turborepo
cd turborepo
npx create-remix@latest ./apps/remix
Enter fullscreen mode Exit fullscreen mode
  • switch the default next app port from 3000 to another port like 3002 so that when they all run together remix can run on port 3000 (idk how to manually set remix port)

  • add version and ui dependency to remix app package.json

/* ./apps/remix/package.json */
{
  "private": true,
  "name": "remix",
  "version": "0.0.0",
...
  "dependencies": {
    "@remix-run/react": "^1.1.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remix": "^1.1.1",
    "@remix-run/serve": "^1.1.1",
    "@remix-run/vercel": "^1.1.1",
    "ui": "*"
  },
...
}
Enter fullscreen mode Exit fullscreen mode
  • supply tsup dependency and scripts to ui package’s package.json ( can swap out whole file)
/* ./packages/ui/package.json */
{
  "name": "ui",
  "version": "0.0.0",
  "private": true,
  "main": "./dist/index.js",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "files": ["dist/**"],
  "scripts": {
    "build": "tsup index.tsx --format esm,cjs --dts --external react",
    "dev": "tsup index.tsx --format esm,cjs --watch --dts --external react",
    "lint": "TIMING=1 eslint src --fix",
    "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
  },
  "devDependencies": {
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "tsconfig": "*",
    "config": "*",
    "typescript": "^4.5.3",
    "tsup": "^5.10.1"
  }
}
Enter fullscreen mode Exit fullscreen mode
yarn
turbo run dev
Enter fullscreen mode Exit fullscreen mode
  • import ui components into remix
/* ./apps/remix/app/routes/index.jsx */

import { Button, CounterButton } from 'ui';
export default function Index() {
  return (
    <div>
      <Button />
      <CounterButton />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • CounterButton
/* ./packages/ui/Counterbutton.tsx */

import * as React from 'react';

export const CounterButton = () => {
  const [count, setCount] = React.useState(0);
  return (
    <div
      style={{
        background: `rgba(255,255,255,.05)`,
        borderRadius: `8px`,
        padding: 16,
      }}
    >
      <p>
        This is component iadasdfsdfdffsfsds from <code>ui</code>
      </p>
      <p>
        <button type='button' onClick={() => setCount((c) => c + 1)}>
          count {count}
        </button>
      </p>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode
  • Add the export from index.tsx
/* ./packages/ui/index.tsx */

import * as React from 'react';
export * from './Button';
export * from './CounterButton';
Enter fullscreen mode Exit fullscreen mode

NX

Install and init the nx workspace and remix app

npx create-nx-workspace@latest
npx create-remix@latest ./apps/remix
yarn
yarn nx dev remix
(or nx dev remix if you have nx-cli installed globally)
Enter fullscreen mode Exit fullscreen mode

The secret sauce of nx workspace is the workspace.json folder in the root as well as the no-hoist element in package.json root (for projects like remix which aren't natively supported by plugins)

  • workspace.json needs project with root and targets
/* ./workspace.json */
{
  "version": 2,
  "projects": {
    "remix": {
      "root": "apps/remix",
      "targets": {
        "dev": {
          "executor": "@nrwl/workspace:run-script",
          "options": {
            "script": "remix dev"
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • root / workspace package.json needs workspaces with packages and nohoist as well as private true and tslib dependency
/* ./package.json */
"workspaces": {
    "packages": [
      "apps/**"
    ],
    "nohoist": [
      "**/remix/",
      "**/remix/**/*"
    ]
  },
"private": true,
  "dependencies": {
    "tslib": "^2.0.0"
  },
Enter fullscreen mode Exit fullscreen mode
  • finally, remix app package.json needs a version, private true and name as well as @remix-run/serve dependency (the dependency should come standard with the install)
/* ./apps/remix/package.json */
{
 "private": true,
  "name": "remix",
  "description": "",
  "license": "",
  "version": "0.0.1",
"dependencies": {
"@remix-run/serve": "^1.1.1",
...
}
Enter fullscreen mode Exit fullscreen mode

credit to Brandon

Update: Nx is making a plugin; they have a preview now

https://www.youtube.com/watch?v=yUuEA4V6DJ0

Top comments (0)