# Sharing code between your backend and frontendĀ  You might want to share files and functionality between your application backend and frontend. This can help cut down on code duplication and ensure consistency between your server and client logic. This can be helpful when building with React Router in framework mode or Remix that support server-side rendering, and use `action` and `loader` functions to handle data fetching and mutations on the server. This guide will walk you through shared folder setup. ## Setting up a shared folderĀ  Follow these steps to start sharing files between you `api` backend and `web` frontend: 1. Create a new root level directory for the folder in your project structure. For example `/shared`. 2. Add your shared files to this folder. You can organize them into subdirectories as needed. Make sure to `export` any functions, classes, or constants you want to share. These exports can be imported into your `api` folder actions and routes using relative filepath imports. For example, to import function `utilFn` from `shared/index.ts`: ```typescript import { utilFn } from "../../shared"; export const run: ActionRun = async () => { // call the function const foo = utilFn(); return foo; }; ``` Or to import `utilFn` from `shared/utils.ts`: ```typescript // Note the change to the import path import { utilFn } from "../../shared/utils"; export const run: ActionRun = async () => { // call the function const foo = utilFn(); return foo; }; ``` 3. Update `vite.config.mjs` so Vite includes the shared folder. Reference your shared folder using the [`server.fs.allow` option](https://vite.dev/config/server-options.html#server-fs-allow): ```typescript import { defineConfig } from "vite"; import { gadget } from "gadget-server/vite"; import { reactRouter } from "@react-router/dev/vite"; import path from "path"; export default defineConfig({ plugins: [gadget(), reactRouter()], resolve: { alias: { "@": path.resolve(__dirname, "./web"), }, }, server: { fs: { allow: [path.resolve(__dirname, "./shared")], }, }, }); ``` Gadget uses `server.fs.allow` under the hood to restrict Vite to the following paths: `["./.gadget/client", "./.gadget/server", "./node_modules", "./public", "./web"]`. This is to ensure only the code you want to make public is bundled and served. Any additions made to `server.fs.allow` in your Vite config will be merged with these default paths. 4. After setting `server.fs.allow`, you can import from your shared folders from inside your project's `web` folder. For example, to import function `utilFn` from `shared/index.ts`: ```tsx // ... other imports import { utilFn } from "../shared"; // ... the rest of your frontend file ``` Or to import `utilFn` from `shared/utils.ts`: ```typescript // ... other imports import { utilFn } from "../shared/utils"; // ... the rest of your frontend file ``` ## Using `resolve.alias` for import aliasesĀ  You can also make use of Vite's `resolve.alias` option to create import aliases for your shared code. This can make your imports cleaner and easier to manage. For example, to create an alias for a `shared` folder in `vite.config.mjs`: ```typescript import { defineConfig } from "vite"; import { gadget } from "gadget-server/vite"; import { reactRouter } from "@react-router/dev/vite"; import path from "path"; export default defineConfig({ plugins: [gadget(), reactRouter()], resolve: { alias: { "@": path.resolve(__dirname, "./web"), "@shared": path.resolve(__dirname, "./shared"), }, }, server: { fs: { allow: [path.resolve(__dirname, "./shared")], }, }, }); ``` And then import using the defined alias, for example, importing `utilFn` from `shared/index.ts`: ```tsx // ... other imports import { utilFn } from "@shared"; // ... the rest of your frontend file ``` Or to import `utilFn` from `shared/utils.ts`: ```tsx // ... other imports import { utilFn } from "@shared/utils"; // ... the rest of your frontend file ```