The web app is built with Next.js 15 and follows a performance-optimized architecture for EVM applications.
- URL-based state management
- API for reading and subscribing to data
- EVM transaction push for writing
- Code organization by route and feature
- Next.js 15's new Turbopack for faster builds
- React Server Components for improved performance
The application uses URL parameters as the source of truth for state management:
import { useSearchParams } from 'next/navigation'
import { createQueryString } from '@l1network/lib'
function Component() {
const [searchParams, setSearchParams] = useSearchParams()
const updateFilters = (filters) => {
const queryString = createQueryString({
...searchParams,
...filters
})
setSearchParams(queryString)
}
}Benefits:
- Shareable application states
- SEO-friendly routes
- Persistent state across page reloads
- Reduced client-side state complexity
The application implements a robust data fetching pattern using React Query:
function useFeatureData(params: FeatureParams) {
return useQuery({
queryKey: ['feature', params],
queryFn: () => fetchFeatureData(params),
})
}Key aspects:
- One subscription per route to minimize connection overhead
- Cached queries for efficient data sharing
- Type-safe contract interactions via viem/wagmi
The project follows a React fractal architecture pattern, where each feature maintains a consistent, self-similar structure across different scales. This approach promotes modularity, scalability, and reusability. For more details, see React Fractal Compoundnents.
app/
├── (routes)/ # Route groups by feature
│ ├── market/ # Market feature
│ │ ├── list/ # Market listing
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ └── detail/ # Market details
│ │ ├── index.tsx
│ │ └── types.ts
│ └── account/ # Account feature
│ ├── index.tsx
│ ├── health.tsx
│ └── types.ts
├── components/ # Shared components
│ ├── layout/ # Layout components
│ └── features/ # Feature-specific components
├── hooks/ # Custom hooks by feature
│ ├── market/
│ │ ├── use-markets.ts
│ │ └── types.ts
│ └── account/
│ ├── use-account.ts
│ └── types.ts
└── lib/ # Utility functions
Key benefits:
- Consistent folder structure across features
- Self-contained, portable components
- Clear separation of concerns
- Scalable and maintainable architecture
- Improved developer experience through predictability
Standardized error handling approach:
import { captureAppError } from '@l1network/errors'
try {
// Implementation
} catch (error) {
captureAppError({
code: 'FEATURE_ERROR',
error,
label: 'featureOperation'
})
}Features:
- Error boundaries for unexpected errors
- Form validation using zod schemas
- Centralized error logging with Sentry
- Next.js 14
- React Server Components
- App Router
- Server actions
- shadcn/ui
- Tailwind CSS
- Radix UI primitives
- viem
- Type-safe Ethereum interface
- wagmi
- React hooks for Ethereum
- @tanstack/react-query
- Data fetching and caching
- zod
- Schema validation
- nuqs
- URL-based state management
- Node.js 18+
- pnpm
- Git
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build for production
pnpm buildPlease refer to the root CONTRIBUTING.md for development guidelines.