v0.18.0 Release Notes

Well, summertime is winding up here in the Northern Hemisphere which means it's time for us to unleash everything we've been working on between family vacations and backwoods camping trips. And let me tell you: it's a LOT of stuff. Buckle your seat belts.

tl;dr Upgrade Guide

  • Upgrade the remix and all @remix-run/* packages to 0.18
  • Add remix setup to your package.json postinstall
  • Add { "paths": { "~/*": ["./app/*"] } } to your tsconfig's compilerOptions
  • If you're using TypeScript:
    • Sorry, you're gonna have to go read the part about our TypeScript improvements!
  • Enjoy the rest of your day

Where's the Transition Stuff?

First of all, I know that some of you have been following the work that Ryan released in v0.18.0-pre.0 and were expecting it to be released in v0.18, however that work is still being refined so we backed it out for this release. We expect it to be released in v0.19 very soon. We just didn't want it to block us releasing all the goodies we've had piling up while it settles.

Sourcemaps

The Remix compiler now outputs sourcemaps for your code on both the server and in the browser. Stack traces on the server will now give you a message in the console that links back to your original source code. This is especially handy when you're using a terminal emulator like iTerm 2 or VS Code that supports ctrl-click on file paths to open a file. Sourcemaps in the browser work as you'd expect.

Huge thank-you to kiliman who got the ball rolling on this one by patching the Remix source code!

Compiler Improvements

The Remix compiler now includes support for using ~ as an import alias for stuff in your app directory. We built this feature by piggy-backing on top of TypeScript's existing convention for path mapping, so the alias is actually defined in your app/tsconfig.json file (or app/jsconfig.json file if you're not using TypeScript).

This means that when app/routes/users/$id.tsx imports app/utils.ts, it can import utils from "~/utils" instead of import utils from "../../../utils".

Note: For now the only alias our compiler supports is ~. We may add support for more in the future.

To add support for this to an existing app, add the following to your tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "~/*": ["./app/*"]
    }
  }
}

Other things the compiler now supports include:

  • dynamic import()
  • importing .css files from packages in node_modules

We also fixed a bug where the compiler would crash when you had syntax errors and we now clean up all the files the compiler generates in dev mode when it shuts down.

TypeScript Improvements

A major goal for us is to have great support for TypeScript out of the box in Remix. This release further improves our TypeScript support by adding a remix.env.d.ts file to the project root. This will be present automatically in new projects created with npm init remix.

The remix.env.d.ts file references all the Remix types that you will need in your project. Previous to this release our types were made available to the TypeScript compiler whenever you imported something from remix. But if you didn't, you weren't able to use them.

If you're upgrading an existing project, add the following to your tsconfig.json:

{
  "include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"]
}

And put the following in remix.env.d.ts in your root directory:

/// <reference types="@remix-run/dev" />
/// <reference types="@remix-run/node/globals" />

Please note that we switched from using the node-fetch types in your node projects to using the built-in DOM types for things like Headers, Request, Response, and fetch. We took this approach because our route modules run in both the browser and on the server, so you'll most likely need the DOM types anyway. And since we can't overwrite the DOM types for these globals, it's better to piggyback on them.

If you need to do node-specific stuff, you can always type cast to get the type you need. For example, if you need to stream the body of an incoming request for doing things like file uploads, you could do something like this to get the right types:

export function loader({ request }) {
  ((request.body as unknown) as NodeJS.ReadableStream).pipe(...);
}

Note: We plan on having much better support for file uploads in an upcoming release, but this should get you by for now.

MDX

Remix v0.18 includes built-in support for handling MDX files, both as route modules (in app/routes) and in import statements. This is great for simple use cases of MDX where you don't have a lot of files.

Read more about our MDX support in the docs.

Netlify Functions

The npm init remix command now supports Netlify Functions as a development and deploy target. As usual, just follow the instructions in the README of your new Remix app to get up and running on Netlify in just a few minutes.

New remix setup Command

The remix CLI has a new command called remix setup for setting up your node_modules/remix directory with all the right files you need in your app.

When we introduced the remix package in v0.17, we relied on postinstall scripts in our various packages to automatically setup the node_modules/remix package with everything it needs so you don't have to remember where to import stuff from. Instead, you can just import it all from remix. However, separate postinstall scripts in our own packages are not guaranteed to run after you have installed everything you need for your app, including other @remix-run/* packages.

The remix setup command is a better solution. Instead of relying on our own package postinstall scripts, remix setup should run in your app's postinstall hook. This means it runs after all of your app's dependencies are installed. It should also be resilient to the way different package managers (npm, yarn, pnpm) do things when installing and removing packages.

This command is already included in the Remix init templates. If you have an existing app that you're upgrading, just add the following to your package.json:

{
  "scripts": {
    "postinstall": "remix setup"
  }
}

Support for Multiple Cookies

Remix v0.18 also adds support for multiple Set-Cookie headers on a single response. If you were trying to do this before, this will be a welcome upgrade.

Aaaaaaand, that's it! We hope you enjoy using this release of Remix as much as we've enjoyed making it for you.