Welcome to the Markly monorepo! This repository contains the codebase for the Markly application, structured as a monorepo managed by Turborepo.
This monorepo is organized into two main directories:
apps/
: Contains the user-facing applications.client/
: The frontend application built with React Router.server/
: The backend API server built with Express.
packages/
: Contains shared code and configurations used across the applications.@markly/jest-presets/
: Shared Jest configurations.@markly/lib/
: A shared library for common functionalities (e.g., environment variable parsing).@markly/typescript-config/
: Sharedtsconfig.json
files.@markly/utils/
: Shared utility functions (e.g., a logger).
Each application and package within the monorepo is a separate workspace.
This monorepo leverages Turborepo to manage builds, tests, and other tasks efficiently. Turborepo understands the dependencies between the workspaces and can run tasks in parallel and cache build outputs.
- The
client
app is a React application using React Router for routing. It interacts with theserver
API. - The
server
app is an Express.js backend that provides API endpoints. - Shared code, like utility functions or configuration files, resides in the
packages
directory and is consumed by the apps. - Docker and Docker Compose are used to containerize the applications, making them easy to build and deploy consistently.
To set up and run the project locally:
-
Clone the repository:
git clone <repository-url> cd markly
-
Install dependencies: This project uses pnpm as the package manager. Install dependencies at the root of the monorepo:
pnpm install
-
Create Docker network: A Docker network is needed for containers to communicate by name. The
|| true
prevents the command from failing if the network already exists.docker network create app_network || true
-
Build and run with Docker Compose: Build the Docker images and start the containers defined in
docker-compose.yml
:docker-compose -f docker-compose.yml build docker-compose -f docker-compose.yml up -d
The
client
application should be available athttp://localhost:3000
and theserver
API athttp://localhost:3001
. -
Shutdown Docker containers: To stop and remove the containers created by Docker Compose:
docker-compose -f docker-compose.yml down
Dependencies are managed at the root of the monorepo using pnpm
. To add a new dependency to a specific application or package (workspace), use the --filter
flag with the pnpm add
command:
# Add a regular dependency to the client application
pnpm add <package-name> --filter client
# Add a devDependency to the server application
pnpm add -D <dev-package-name> --filter server
# Add a dependency to the @markly/lib package
pnpm add <package-name> --filter @markly/lib
Replace <package-name>
and <dev-package-name>
with the actual package names you want to add, and <workspace-name>
with the name of the app or package (e.g., client
, server
, @markly/lib
, @markly/utils
, etc.).
This monorepo is configured to be built with Docker and Docker Compose. The docker-compose.yml
file defines the client
and server
services.
To build all apps in this monorepo using Docker Compose (after installing dependencies and creating the network as described in Getting Started):
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker-compose -f docker-compose.yml build
To start the containers defined in docker-compose.yml
:
docker-compose -f docker-compose.yml up -d
Open http://localhost:3000 for the client and http://localhost:3001 for the server status endpoint.
To shutdown all running containers started by Docker Compose:
docker-compose -f docker-compose.yml down
Tip
Vercel Remote Cache is free for all plans. Get started today at vercel.com.
This example includes optional remote caching. In the Dockerfiles of the apps (apps/client/Dockerfile
and apps/server/Dockerfile
), uncomment the build arguments for TURBO_TEAM
and TURBO_TOKEN
. Then, pass these build arguments to your Docker build commands.
You can test this behavior using a command like:
docker build -f apps/client/Dockerfile . --build-arg TURBO_TEAM="your-team-name" --build-arg TURBO_TOKEN="your-token" --no-cache
This Turborepo has some additional tools already setup for you:
- TypeScript for static type checking
- ESLint for code linting
- Jest test runner for all things JavaScript
- Prettier for code formatting (Note:
client
usesprettier-plugin-tailwindcss
) - Biome for fast formatter and linter (configured in
client
andserver
) - TailwindCSS for styling (
client
) - @t3-oss/env-core for type-safe environment variables (
lib
)