Organizing full-stack React app with Express - sharing code between client and server

I’m working on a full-stack application using React for the frontend and Express for the backend. Right now I have this folder setup:

project
├── client
|   ├── node_modules
|   ├── public
|   ├── src
│   │   └── App.js
|   ├── package.json
|   └── tsconfig.json
├── server
|   ├── node_modules
|   ├── public
|   ├── src
│   │   └── index.ts
|   ├── package.json
|   └── tsconfig.json

This looks clean to me because both parts have their own dependencies and configs. But now I need to share some utility functions and types between the client and server sides.

I tried creating a common folder at the root level with its own package.json and everything. On the server side I can import from it using path aliases like:

import { helperFunction } from @common/utils;

But for the React side (built with create-react-app), I would need to do:

import { helperFunction } from '../../common/src/utils';

The problem is create-react-app doesn’t allow imports from outside the src folder and I don’t want to eject because I’m not comfortable managing webpack configs myself.

Should I put the shared code inside the React src folder instead? Or is there a better way to structure this kind of project? I’m new to React and would love to know what the standard approach is for this situation.

I faced a similar issue in a full-stack project. Instead of struggling with create-react-app’s import limitations, I suggest organizing your project with a monorepo structure using tools like npm workspaces or Yarn workspaces. This way, you can have a root package.json and separate folders for your client, server, and shared code. It allows cleaner imports and easier dependency management, as you’d simply reference the shared utilities without worrying about path issues. It might take some initial setup time, but it simplifies code sharing significantly, especially as your project grows.

have you tried symlinks? create symbolic links from client/src to your common folder - CRA will think the shared code’s inside src when it’s actually in your common directory. what utilities are you sharing? would help to know so we can suggest better options.

just copy-paste the shared code into both client and server for now. it’s not ideal, but CRA makes dealing with external imports a pain. your shared utils should be small anyway. later, you can switch to a monorepo setup or eject when you’re more confident with webpack.