logo
▼
Projects
Collaborations
Resources
Our Partners
Our Community
Projects
Collaborations
Resources
Our Partners
Our Community
Account
Sign InJoin UsHelp & Support

The Cometbid
Technology Foundation

Empowering innovation through open-source collaboration. TCTF supports developers, organizations, and communities worldwide in building the future of technology with transparent, vendor-neutral governance and world-class open-source projects.


Follow Us

Our Community

  • About Us
  • Upcoming Events
  • Projects
  • Collaborations
  • Membership
  • TCTF Training
  • Corporate Sponsorship

Learn

  • FAQ
  • TCTF Incubator Programs
  • Brand Guidelines
  • Logo Specifications

Legal

  • Privacy Policy
  • Terms of Use
  • Compliance
  • Code of Conduct
  • Contribution Guidelines
  • Legal & Trademark
  • Manage Cookies

More

  • Report a Vulnerability
  • Report Bugs
  • Mailing Lists
  • Contact Us
  • Support
  • Support Tickets
  • TCTF Social Network

Subscribe to our Newsletter

Frontend Architecture: Monorepo, Next.js, and Shipping 4 Apps from One Repo
Engineering12 min read

Frontend Architecture: Monorepo, Next.js, and Shipping 4 Apps from One Repo

TypeScript on the frontend was never a debate — same language as the backend and infrastructure. Next.js won on ecosystem maturity and Server Components. Nx + pnpm workspaces manage 4 apps and shared packages from one monorepo. The tradeoffs are real, but the alternative — duplicated code and version drift — is worse.

May 11, 2026· 12 min read
Sam Adebowale
TCTF Blog
Home›Blog & Videos›Frontend Architecture: Monorepo, Next.js, and S...

In This Article

  • TypeScript on the Frontend: Same Language, Same Mental Model
  • Next.js: The React Framework That Ships
  • The Monorepo Decision: Nx + pnpm Workspaces
  • Managing 4 Apps + Shared Packages
  • The Tradeoffs: What Monorepo Costs You
4Apps
4+Shared Packages
Next.jsFramework
NxBuild Tool

The frontend architecture of TCTF is shaped by the same principle that shapes the entire stack: TypeScript everywhere. The same language that runs in our Lambda functions and defines our CDK infrastructure also powers our React components, our build scripts, and our test suites. This is not a coincidence — it is a deliberate architectural decision that compounds in value as the project grows. On top of TypeScript, we chose Next.js as the React framework, Nx + pnpm workspaces for monorepo management, and a shared package architecture that lets four applications share components, types, utilities, and an API client without duplication. This article covers the decisions, the tradeoffs, and the lessons learned from shipping four frontend applications from one repository.

01TypeScript on the Frontend: Same Language, Same Mental Model

TypeScript on the frontend was never a debate. It was the default from day one, and the reasons are the same as the reasons for TypeScript on the backend: one language for the entire stack means zero context switching.

A developer reading a Lambda handler can immediately understand the React component that calls it because both are written in TypeScript. The request types in the handler match the request types in the API client. The response types in the handler match the response types in the component. The error types thrown by the handler match the error types caught by the component. There is no translation layer, no impedance mismatch, no mental model switch.

This is the compounding advantage of TypeScript-everywhere. Each additional layer that uses TypeScript increases the value of every other layer. When the backend, the infrastructure, and the frontend all share a type system, changes propagate through the entire stack with compiler assistance. A field rename in the OpenAPI spec generates new TypeScript types that break the Lambda handler and the React component simultaneously — both are fixed in the same pull request, and the integration is guaranteed to work.

The alternative — TypeScript on the frontend and Python or Java on the backend — creates a boundary where type safety stops. The frontend has types, the backend has types, but the boundary between them is untyped. That boundary is where integration bugs live. TypeScript-everywhere eliminates the boundary entirely.

The practical benefit for the team is mobility. Any developer can work on any part of the stack without learning a new language. A frontend developer can review a Lambda handler PR. A backend developer can fix a React component bug. The shared language makes the team more flexible and reduces the bottleneck of specialized knowledge.

🔗

TypeScript on the frontend was never a debate. Same language as the backend, same language as the infrastructure. A developer can read a Lambda handler, a React component, and a CDK stack without switching mental models.

Multiple screens with code — representing the multi-app development workflow where three Next.js applications share components and types from a single monorepo.
Multiple screens with code — representing the multi-app development workflow where three Next.js applications share components and types from a single monorepo.

02Next.js: The React Framework That Ships

We evaluated three React frameworks: Next.js, Remix, and Gatsby. Each has strengths, but Next.js won on three criteria: ecosystem maturity, the App Router with Server Components, and the deployment story.

Ecosystem maturity matters for a project of this scale. Next.js has the largest community, the most third-party integrations, and the most production deployments of any React framework. When we encounter an issue, the answer is usually a search away. When we need a library, it usually has Next.js-specific documentation. The ecosystem reduces the number of problems we need to solve from scratch.

The App Router with Server Components is the architectural feature that tipped the decision. Server Components render on the server and send HTML to the client — no JavaScript bundle for components that do not need interactivity. For a content-heavy platform like TCTF, this reduces the client bundle size significantly. Pages load faster because the browser downloads less JavaScript. The combination of Server Components for static content and Client Components for interactive elements gives us the best of both worlds — fast initial loads and rich interactivity where it matters.

The deployment story sealed the deal. Next.js deploys seamlessly to Netlify with automatic SSR support, edge functions, and image optimization. The build output is optimized for the deployment target, and the platform handles scaling, caching, and CDN distribution. We do not manage servers for the frontend — the deployment platform handles everything.

Remix was a strong contender with its focus on web standards and progressive enhancement. Gatsby was eliminated early — its static site generation model does not fit a platform with dynamic, authenticated content. Next.js was the framework that matched our requirements across all dimensions.

⚛️

Next.js won on ecosystem maturity, Server Components for reduced bundle size, and seamless deployment. Server Components for static content, Client Components for interactivity — the best of both worlds.

TCTF monorepo structure — 4 apps (the public portal, the community platform, the admin dashboard, and the helpdesk) sharing shared packages managed by Nx build orchestration and pnpm strict dependency isolation.
TCTF monorepo structure — 4 apps (the public portal, the community platform, the admin dashboard, and the helpdesk) sharing shared packages managed by Nx build orchestration and pnpm strict dependency isolation.

03The Monorepo Decision: Nx + pnpm Workspaces

For a project with four frontend applications and multiple shared packages, a monorepo is not optional — it is essential. The alternative is separate repositories for each application, which means duplicated shared code, version drift between packages, and integration testing across repository boundaries. We chose Nx for build orchestration and pnpm workspaces for package management.

Nx provides the intelligence that makes a large monorepo manageable. The dependency graph tracks which packages depend on which other packages. When a shared component changes, Nx knows which applications need to be rebuilt and tested. The affected command runs only the tasks that are impacted by the current changes, which keeps CI times reasonable even as the repository grows.

Nx also provides computation caching. If a package has not changed since the last build, Nx skips the build and uses the cached output. This applies to builds, tests, and linting. In a monorepo with dozens of packages, caching reduces build times from minutes to seconds for unchanged packages.

pnpm workspaces handle package management with strict dependency isolation. Unlike npm or yarn workspaces, pnpm uses a content-addressable store and symlinks to ensure that each package sees only its declared dependencies. A package cannot accidentally import a dependency that it does not declare in its package.json. This strictness catches dependency issues at development time rather than in production.

The combination of Nx and pnpm gives us the best of both worlds: intelligent build orchestration that scales with the repository size, and strict dependency management that prevents the dependency chaos that plagues large monorepos.

🏗

️ Nx provides the dependency graph, affected detection, and computation caching. pnpm provides strict dependency isolation. Together, they make a large monorepo manageable instead of chaotic.

Responsive web design displayed on a laptop — representing the four frontend applications (the public portal, the community platform, the admin dashboard, and the helpdesk) shipping from one monorepo with shared packages.
Responsive web design displayed on a laptop — representing the four frontend applications (the public portal, the community platform, the admin dashboard, and the helpdesk) shipping from one monorepo with shared packages.

04Managing 4 Apps + Shared Packages

The monorepo contains four applications and multiple shared packages. The applications are the public portal (blog, documentation, and marketing pages), the community platform (profiles, projects, messaging, and social features), the admin dashboard (internal management and analytics), and the helpdesk (support ticketing and knowledge base). The shared packages include data synchronization utilities, internationalization with translation management, and the shared API client that provides typed methods for every backend endpoint.

The shared packages are the connective tissue of the monorepo. When a developer adds a new API endpoint, the shared API client package is regenerated from the OpenAPI spec, and both tctf-main and tctf-social-network immediately have access to the new typed method. When a translation is added to shared-i18n, both applications can use it without any coordination. When a data utility is improved in shared-data, both applications benefit.

Changes to shared packages automatically trigger rebuilds of dependent applications. Nx's dependency graph ensures that nothing ships with stale dependencies. If shared-i18n changes, both tctf-main and tctf-social-network are rebuilt and tested. If shared API client changes, every application that imports it is verified against the new types. The dependency graph is the safety net that prevents version drift.

The package boundaries are enforced by Nx's module boundary rules. An application cannot import directly from another application's source code — it must go through a shared package. This prevents the tight coupling that turns a monorepo into a monolith. Each application can be built, tested, and deployed independently, even though they share code through well-defined package interfaces.

The practical workflow for a developer is straightforward. They work in one application or one shared package at a time. Nx handles the build orchestration, dependency tracking, and cache management. The developer focuses on the code, and the tooling ensures that changes propagate correctly through the dependency graph.

📦

Four apps — the public portal, the community platform, the admin dashboard, and the helpdesk — plus shared packages, all in one repo. Changes to shared packages automatically trigger rebuilds of dependent apps. The dependency graph prevents version drift.

05The Tradeoffs: What Monorepo Costs You

Monorepos are not free. The benefits of code sharing, consistent tooling, and atomic changes come with real costs that grow as the repository grows.

Build times increase with repository size. Even with Nx's affected detection and computation caching, a change to a widely-used shared package can trigger rebuilds of multiple applications. CI pipelines need to be smart about what to build — running all tests for all applications on every PR would take over an hour. We mitigate this with affected-based testing, but the CI configuration is more complex than it would be for a single-application repository.

Dependency conflicts between applications require careful management. If tctf-main needs version 4 of a library and tctf-social-network needs version 5, pnpm's strict isolation helps but does not eliminate the problem. Shared packages must be compatible with all applications that use them, which sometimes means upgrading all applications simultaneously or maintaining backward compatibility in shared code.

IDE performance degrades with large repositories. TypeScript's language server needs to process more files, autocomplete takes longer, and file search returns more results. We mitigate this with project references and incremental compilation, but the IDE experience is noticeably slower than it would be in a smaller repository.

The learning curve for Nx is non-trivial. New developers need to understand the dependency graph, the affected command, the caching system, and the module boundary rules. This is additional tooling knowledge that is specific to the monorepo setup and does not transfer to other projects.

Despite these costs, the alternative is worse. Separate repositories mean duplicated shared code that drifts over time. Integration testing across repositories is harder than integration testing within a monorepo. Version management for shared packages adds overhead that Nx's dependency graph eliminates. The monorepo tradeoffs are real, but they are the better set of tradeoffs for a project of this scale.

⚖️

Monorepo costs are real: build times, dependency conflicts, IDE performance, tooling complexity. But the alternative — duplicated code, version drift, cross-repo integration testing — is worse at this scale.

The frontend architecture is TypeScript everywhere, Next.js for the framework, Nx + pnpm for the monorepo, and shared packages for code reuse. Every decision reinforces the others. TypeScript connects the frontend to the backend through shared types. Next.js provides the rendering model that balances performance and interactivity. The monorepo enables code sharing without version drift. The tradeoffs are real — build times, dependency management, IDE performance — but they are the right tradeoffs for a platform that ships four applications from one repository.

Editor's Note: This is Part 2 of the 'Building TCTF' series. Read the full series for the complete story of our technology decisions.
ReactTypeScriptPerformance

Never miss a post

Subscribe to get the latest TCTF articles delivered to your inbox.

Subscribe
PreviousThe Backend Stack: TypeScript or Nothing, CDK or Bust, DynamoDB All the Way
NextThe Social Network That Pays You, Part 1: How Cometbid Social Brings Earning to Professional Networking

In This Article

  • TypeScript on the Frontend: Same Language, Same Mental Model
  • Next.js: The React Framework That Ships
  • The Monorepo Decision: Nx + pnpm Workspaces
  • Managing 4 Apps + Shared Packages
  • The Tradeoffs: What Monorepo Costs You

Browse by Month

May
  • TCTF's Achievement System: Prove Your Skills, Not Just Claim Them
  • Why AI Makes Human Skills More Valuable — and How TCTF Helps You Stay Ahead
  • Open Source Is Not Just for the Elite — How TCTF Makes Contributing Easy for Everyone
  • Skills Over Degrees: 3 Trends Reshaping Tech Careers in 2026
  • The Social Network That Pays You, Part 1: How Cometbid Social Brings Earning to Professional Networking
  • The Backend Stack: TypeScript or Nothing, CDK or Bust, DynamoDB All the Way
April
  • Why Africa Does Not Boast a Vibrant Open-Source Community — and Why TCTF Is Working to Change That
  • Enterprise Involvement in Open Source Is Critical for Africa's Growth in Tech
  • Building Your API Stack in 2026
  • How Collaboration Makes Us Better Designers
March
  • Our Top 10 JavaScript Frameworks to Use in 2026
  • Why Africa Lags in the Open-Source Community and How to Fix It
  • Mastering Design System Documentation
  • Product Roadmap Strategies for 2026
February
  • Why Open Source Is the Lifeblood of Tech — and Critical for African Startups
  • Microservices Architecture Patterns That Actually Work
  • Accessibility-First Design Principles
  • Cloud-Native Development Essentials
January
  • The Rise of Edge Computing: Why Your Next App Should Run Closer to Users
  • Open Source Sustainability: Funding Models That Work

More From TCTF Blog

The Backend Stack: TypeScript or Nothing, CDK or Bust, DynamoDB All the Way16 min read

The Backend Stack: TypeScript or Nothing, CDK or Bust, DynamoDB All the Way

The technology stack is the single most important decision in a software project. For TCTF, the answer is TypeScript everywhere, AWS for infrastructure, CDK for deployment, DynamoDB for data, and Next.js for the frontend. This is the story of how we got there — including the IaC journey through 7 tools, the almost-WordPress disaster, and the December 2025 rewrite that made microservices real.

May 4, 2026
Building Your API Stack in 202612 min read

Building Your API Stack in 2026

Explore modern approaches to building scalable API architectures. Learn about REST, GraphQL, API gateways, authentication strategies, and best practices for designing robust API ecosystems.

April 14, 2026
Our Top 10 JavaScript Frameworks to Use in 202614 min read

Our Top 10 JavaScript Frameworks to Use in 2026

An in-depth comparison of the most popular JavaScript frameworks in 2026. Explore React, Vue, Angular, Svelte, and emerging frameworks to find the best fit for your next project.

March 28, 2026