Remixing Your Stack in a Monorepo Workspace

Rate this content
Bookmark

Remix entered the stage with a unique and refreshing take on how to develop on the web. But how do you integrate it into your existing ecosystem of applications? Do you want to test-drive Remix on a small project, or do you want to go full-in, but it is tricky to do a big-bang migration from your existing React app? In this talk, we're going to explore how a monorepo-based code organization can help integrate Remix with your existing React and TypeScript infrastructure, facilitating high code reuse and a migration path to Remix.

22 min
18 Nov, 2022

Video Summary and Transcription

Let's talk about remixing our stack in a Monorepo workspace, which allows for incremental migration and is suitable for transitioning from a Next.js app to a remix stack. Refactoring may be required for feature-specific and Next.js-coupled components, but the process is simplified because the features have already been moved out. Configuring the Monorepo to reference packages locally and linking them to the Next.js application is necessary. Nx provides benefits like fast refreshing, pre-configured setups, and features like local and remote caching.

1. Remixing Stack in Monorepo Workspace

Short description:

Let's talk about remixing our stack in a Monorepo workspace. Your routing files should configure the routing for your specific stack, while the implementation of the feature should live elsewhere. You can organize your code by having a routing folder and a features folder inside your application. Alternatively, you can move the features into a dedicated packages folder, resulting in a clean and encapsulated structure. This setup allows for incremental migration and is suitable for transitioning from a Next.js app to a remix stack.

How to Remix Your Stack with ReactJS

Hey, let's talk about how we can remix our stack in a Monorepo workspace. And I would like to start with a quote, or actually a tweet from Ryan Florens from a couple of weeks ago, where he actually made a quite powerful statement and mentions that your routing files should actually just configure the routing for your specific stack. The actual implementation of that feature that's being visualized there, should live somewhere else, right? So, you import it, but then specifically depending on the stack you have, you configure the routing and you import it, and then it gets bundled and visualized on the webpage.

And this is a very powerful mechanism for architecting your system, but also for organizing your code. And we can take this even further. So normally, we see exactly this type of structure, what Ryan Florence mentioned. So you have kind of your application, you have the routing folder, which can be pages, routes, app, whatever. And then you should have, as Ryan mentions, like a different folder potentially inside that app, which is like your features. And then you have like the different folders for all those features. And the routing simply imports from them.

Now we could actually go a step further and even move them out of the application into dedicated packages folder. So this new structure, what you see now is we have an apps folder and now we have a packages folder. And in the apps folder, we still have our application with its routing mechanism. And then in the packages folder, we now have different folders for all of our features. And all of these features are now nicely kind of independent encapsulated, and they have a very clean API point where there is an index.ts file which exposes everything that can be used outside and everything else kind of remains inside that package. So you can imagine we get a very clean structure having such a setup here. Obviously, we can go ahead and just import as before. Our import might even look like as if we consumed it from some external package like some MPM registry. But it actually is just consumed locally in this case. But you can see it here from such an import statement.

So how does this help, actually? Well, potentially with something like incremental migration. Now, you might have noticed that in my example, I used a Next.js app, right? There's that pages folder. Well, if you use the new features or opt into new features, you might have a different routing folder there. But this was not by accident, but it was intentional. So you might nowadays have like a Next.js application with some already built in features, with some like an application that has been developed already for a couple of months or even years. And you might want to kind of slowly move over to a remix stack because for whatever reason, that is more suitable for you. So this is exactly what you could achieve in such a setup, because as you can see, our actual Next.js app and the actual feature folders are kind of already separate and nicely. And if you pay attention, this is actually already a monorepo. If you want, right. We have just a single app in there, but we have an app.

2. Adding Applications and Refactoring Features

Short description:

We can add another application to the monorepo and generate a new remix app. This allows us to migrate new features or keep both apps depending on the use case. Refactoring may be required for feature-specific and Next.js-coupled components. The process is simplified because the features have already been moved out. Juergen Stromflohner, a web technologies expert, demonstrates how this works using Annex, an extensible build system. The Next app with the features folder is organized, and refactoring involves creating folders, moving the app, and making the features autonomous with their own package.

We have a couple of packages. So this is totally a monorepo, a very simple one. So what we could do is we could just add another application in that case. For instance, add a new remix app, which is our target migration destination. Right. So where we want to move over new features or where we even want to keep them both depending on the use case or deployment strategy.

So we could just generate a new remix app with the create remix command and then just add that app inside our monorepo workspace and import the features that we already have. There might be some various feature specific things or even things that are coupled to the Next.js application, obviously. So those need or might need some refactoring. But it's much easier because there have already been moved out.

So how does this work in practice? Let me show you. But first, my name is Juergen Stromflohner. I'm a good developer expert in web technologies. I'm also an ACAD instructor. And I work as the director of developer experience for a tool called Annex. And Annex is a smart, fast, extensible build system that happens to work really well for monorepo setups and application structures that we have just discussed. So let's have a look.

So I have here my Next app with that features folder, which gets imported directly from our routing configuration. And those features are actually nicely organized. So there is an index.js file which exports our functionality, which is super simple. And then we have also the design system which exports here a single button. But this is organized in the same fashion. So how would we refactor this to get such a monorepo workspace with a more modular structure? Well, first of all, we would probably go ahead and create the folders. And by the way, these are fully up to you, however you name this. The normal naming is what you find out there is like apps and packages or Apps and Lips. But it's up to you how you want to choose those. And we would probably go ahead and move our next app in this case into this app folder. As the next step, we need to factor out these features and move them to their packages folder. So they are completely independent. And as a result, we should also now make all of these autonomous in a sense that they have their own package.

3. Configuring Monorepo and Linking Packages

Short description:

Let's configure the Monorepo to reference packages locally. Install the dependencies at the root of the package and link them to the Next.js application. Reference the dependencies in the Next.js app's package.json. Build the packages to generate the necessary output files. Run the Next.js application.

Their own dependencies, their own build scripts and things like that. So let me set that up for you quickly. So here we go.

We now have a source folder where the files live. We have a nearest build config here to our simple one. Each of these packages has now its package. JSON with the name build script in this case, and its own dev dependencies. And the very same setup holds for that design system package as well.

Now, the next step is we need to actually configure that Monorepo to tell NPM that whenever we reference a package, it should reference it locally rather than globally. So to do that, we need a root level package JSON here. So that package JSON is the configuration of our Monorepo. So there is most importantly that workspace property, which defines what our local folders are, where packages should be linked between each other. It might also have some global dev dependencies, as well as dependencies that all of the packages in the workspace should share among them.

But as a next step, we can go ahead and install all those dependencies at the very root of the package. So with this, we should now be able to actually link here our packages to our next JS application, because obviously our previous import, as you have seen here from the local features folder, doesn't work anymore because those features don't exist anymore. Rather, we should now go ahead and actually link them to where they are now moved. And so in this case, I would go here for the authentication feature and import it from here, my org auth, as well as here for this one, I would have here, my org design system.

But we also need to reference those dependencies in our next JS app. So we would go here in the package json of our next JS app in the dependencies folder, and reference here my org design system. And we can reference it with a star because we're not really interested in a specific version, although we could, but we rather want to consume the latest version that lives locally here in our workspace. And we do the very same for our auth part.

Now let's install the dependencies again so npm can do the proper linking. But before we can then actually consume them, we also need to build these packages, because obviously those depend on the build output of compiling this to a JavaScript file. So let's go ahead and build those. So we can run npm run build and then we can give it the workspace flag here and say my org auth. We should now go ahead and build our authentication library. And you can see here, it produced a dist folder, it produced like the index DTS files. So we can do the same thing here also for our design system library. So we again run the build and we similarly will get here a dist folder with the compiled files. So if you now go ahead and run our next JS application.

4. Issues with Setup and Dependencies

Short description:

In the setup, there are some issues in terms of the DX. We need to ensure there is a build for the auth and design system packages. If we change something in those packages, we need a watching process to refresh the application.

It would totally work. You can see here, we get the name printed out as well as our small button visualized on the web page. So you might have noticed that there are some things in the set up which are not ideal, especially in terms of the DX. Because for instance, whenever we run our next JS application, we need to make always sure that there is a build already run for our auth and design system packages. So we need to have that dist folder already there because our next app depends on those build outputs. And similarly, also, if we change something in those packages folders, you need to be some watching process that kind of refresh the actual application.

5. Adding an X to the Monorepo Workspace

Short description:

Adding an X to the monorepo workspace is straightforward. Run the npx nx at latest command and the init script to add the nx package. Configure the scripts that need to be run in order, such as the build script. Nx has a caching feature that allows selecting cacheable scripts. The setup includes a new NxJSON file with cacheable operations and a target default. Running the build command for a package or application will build its children first and then itself. The Nx commands can be used for more convenience. Rerunning the build command will use the cache. The setup can be configured to run in development mode.

Now, adding an X for instance, can help with some of these things. So let's do that. Adding an X is pretty straightforward. So you run the npx nx at latest command and you run an init script. And what this will do is it will add the nx package to this monorepo workspace. And then we'll ask you already a couple of questions to configure it. First of all, the first question is exactly what I mentioned before. So is there any, are there any scripts that need to be run in order? And our build script, as we have just mentioned, definitely needs to be run in order because we need to run the dependencies first. Similarly, an X has a caching feature. And so it asks like which of those scripts are cacheable? So def and start, probably not because that's really just about the development, but build, def and is potentially, if we would have test or linting scripts as well, those would be too. So let's select build here. We could even customize the output folder if there is any, but most commonly this build, publish, public are already covered and then also if we want to enable distributed caching. So we can definitely opt in here and install that. So now what we got here in this setup is we got a new NxJSON. So first of all, there's a new dependency with an X here in our package, JSON at the very root. We have also this NxCloud package because we opted in into the distributed caching. And the more interesting part here is that NxJSON file, which has the cacheable operations defined and the target default as well. So this is exactly the type of operation, which I mentioned before, which makes sure that whenever we run the build of some package or application, it runs the build of all its children first, and then the build itself. So let's try this out immediately. If we, for instance, remove here auth and design system, the dist folders. And then we run the build of my next app. You can now also use the Nx commands, which are more handy because we can just run Nx build and then here choose my org my next app. And so you can see now it runs two dependent project builds, which are exactly our dependencies that we have. And then it runs the actual application build of our next Jazz app. And the cool part is like, if we rerun this now it is cached. So it would immediately be split out and we can even configure this setup. So we can go ahead and say we don't just want to run this for actual build command, but also if we run in development mode for our setup.

6. Leveraging the Monorepo Setup

Short description:

To leverage the migration part, we add a remix app to the monorepo setup. The packages are linked to the remix application, allowing us to import and use them. By pre-building the dependent projects and running the remix application, we can see the flexible and configurable setup in action. Another setup option is the integrated monorepo workspace, which comes pre-configured with plugins to simplify development. With the Ennex console extension, we can generate and configure React and JavaScript libraries, automatically linking them with the global TS config base.

So now that we have this workspace, this monorepo setup configured, how can we now leverage this migration part? Well, let's add a remix app. So all I'm going to do is just cd into that apps folder and then run the create remix app. So I call it my remix app. I just want to have the basics, remix app server. I want to have typescript, and then I can just add it to my workspace. If I here navigate out to the root of my package and run npm again, it would set up and recognize now also my remix application, which lives alongside my Next app.

And so now that we have this setup, we can actually go ahead and just link to packages just in the same way we did in our Next.js app. So I can go ahead and here, take these two packages, go to the remix application, add those as well here into my system, and now I could go and import them from the remix routes. So now we have our buttons here imported. We can just go ahead and say here, welcome to remix. And that's here. Let's say our button just below it. Let's install the dependencies such that like npm can link everything together. And now we can run our remix application. If we first, again, pre-build our two dependent projects like the auth and design system library, but now if we go to localhost 3000, we have our remix app running and we also have the button included.

So what we have seen here is a very flexible setup where we can configure the tooling, however we want. But in order so we also have to configure them. So this is what we call a package-based monorepo setup, where all of these packages are potentially independent, they have their own dependencies, you can choose the build tooling that you want to have and you need to configure everything so that it works as it is intended to work. Now let me show you a different setup, which we call integrated monorepo workspace, which Ennex is capable of setting up for you. And the difference there is it comes pre-configured, also more opinionated, but it has a set of plugins that help you in the development of your project. So in this case, again, we have our Next.js application, but for instance, also for our packages or libraries, we can generate them, we can preset them up and we don't have to worry about how the setup is being done. So by having this Ennex console extension installed, I actually can even go ahead and just right click, select here a React library, which is my design system that I want to configure. And have that generated for me, and so this would set up the design system in a certain way for me already with a lib folder, a couple of facilities in here that I can then consume from within my application. Similarly, I can go ahead and configure my Auth library, but in this case, I could say this is really just a normal JavaScript library. There is no React in there. So let me choose here the novel JS plugin and define my auth package and just generate that as well. So all of these are automatically here configured and linked with our global root level TS config base. So rather than using here something like NPM workspaces or pnpm or yarn workspaces, this is done over some typescript path mappings. The experience is actually exactly the same because we can still go to our Next.js app into the pages folder here into our file and just import something from that auth folder. So we can go here to auth and then whatever we have exported there we can import it into my application.

7. Automatic Refresh in Auth Folder

Short description:

In this setup, the application automatically refreshes whenever a change is made in the auth folder. No additional setup or scripts are required.

The experience here is very nice because what we can do here, for instance, if I return the name, I can go here and I can reference that. And so when I run my application, it automatically would refresh the application whenever I change something in that auth folder. So I can go ahead and just serve here my next app. And so if I navigate to 4200, you see here my next app being run. I see here John Doe. And if I go back to my auth application on my auth library and add a couple of exclamation marks, you go back, you see it is automatically refreshed. So that is already wired up for you. You don't have to kind of set up any prebuilt steps or any watcher scripts, but this works out of the box.

8. Adding Remix App and Integrated Setup

Short description:

To add a remix app, install the remix package and generate a new remix application. Reference and import things the same way as in the Next.js application. Run the remix app, and it will load up, show John Doe, and work with live refresh. The integrated setup pre-configures the stack and provides generators for remix actions, loaders, and metadata.

So what if I want to add now a remix app to this? Well, I can just go ahead and install the remix package, the remix plug-in here. And so once I have the plug-in installed, I can go ahead and generate a new remix application, so I can again run NX generate application. Now I should see the Now Remix app. I give it the name, I can give it a couple of options if they are available, and then I generate the remix app inside my app folder as we did before.

And so now that I have my remix app set up here, I can just go ahead and actually also reference and import things the same way as I did in my Next.js application. So I go back to my remix app inside the routes folder. I import auth package and just use it the very same way. Let's actually run the remix app. So then if we load the remix app, we can see it loads up, it shows John Doe, and it also works with live refresh. So if I go back to my auth part here, I remove the exclamation marks again, I go back, you can see it already refreshed and visualized the result for me. And so this is really just the tip of the iceberg here. The main advantage of such an integrated setup is that it pre-configures the stack for you. So you can actually focus on structure in your workspace, but you don't have to worry about how to build those, where to pre-build those and moreover, it comes with facilities such as those generators, which we have seen, which can do even more, such as here generating remix actions, loaders, metadata for your routes and much more.

9. Benefits of Modular Structure and Nx

Short description:

In a monorepo workspace, applications become thin and handle bundling, while packages are encapsulated with well-defined boundaries. This allows for easy portability and scalability with teams working on specific packages. The modular structure enables isolated testing and diversifying the stack with different tech stacks. Nx helps manage and scale the setup, offering benefits like fast refreshing and pre-configured setups. Nx also provides features like local and remote caching and a dedicated Visual Studio code extension.

So what's more, this is really a different approach to how you organize and structure your code in such a monorepo workspace. Because what happens here is that your applications at the very top become very, very thin and they are really just the bundling part of your tag-specific setup. So this is where you include the components into your routing, how that specific tag like the next.js or remix setup demands for it, while the packages down there are more encapsulated, they are well-defined, they have well-defined API boundaries usually, and they can even be tag-agnostic.

So they don't have to, because some of those might be feature-specific things where we even expose like remix loaders, which you include in a remix application. But things like the authentication workflows can totally be tag-agnostic and be written in pure TypeScript. And so as you can imagine, this allows for much easier portability of features. And even though if you have to refactor things, it's much easier if they have already been extracted.

What you also get most interestingly is that you can run for instance the visualization of a graph. So this is specific to Nx, where you can run a Nx graph and it will show you now the structure of your application. Now in our super simple setup, we really just have two apps which depend on both labs. But in a more evolved setup, this might get more complicated. And most importantly, also this type of setup scales with your team. It is very easy now to for instance allocate teams to those specific packages where one works on the authentication part, there's another set of people and developers that work on the design system part, that are more shared across different apps that you might have. But then there's also like features such as a product list, where another team works on that is just focusing on the business aspect of the application. And also now that you have those more fine-grained packages, you can even run the tests in an isolated mode against just the product list, just the authentication part. So it's even easier to figure out like what is going wrong if tests fail because they are very easily identifiable. And moreover, if you now run this even on CI, given that graph that is now present, it's impossible to just run things that got touched. For instance, let's say we touch a single node in that graph, then only those would be actually tested and built and linked in your CI system. At the same time, this is also a way for diversifying your stack. Because as we have seen, we start from a Next.js application and have the intention of adding a remix app and then migrating pieces over. And you might even have multiple applications, multiple different text stacks at the same time, which you deploy to different type of destinations of your organization. And this is all thanks to that modular structure where the apps are decoupled from the actual modular packages. So we in particular have also seen today how we can implement such a stack with Nx and how that can help.

Now, we have seen two different approaches of how to use Nx in this setup. The first one is probably more ideal if you have an existing stack already. So let's say you have that npm workspace already in such a configuration. But now you want to add Remix to it, and you want to have Nx to help you manage that and scale that as it grows. If you start new, you probably lean towards the more integrated type of configuration, which gives a lot of more benefits, such as all that fast refreshing. The watching already works. But at the same time, it gives you that pre-configured setup where you don't have to worry about all the lower level details on your own. The cool part here is really that Nx helps you not only scale as you grow with features such as local and remote caching, but also comes with some nice DX aspects, such as dedicated Visual Studio code extension that can help you develop it in the long run. So if this sounds interesting, definitely join us and follow us on Nx Dev Tools, on Nx.dev, which is the main website, or also chime in to our community Slack, which you can find on the slide here.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn