Optimize Your dApp for Production
When preparing your Scaffold-Stark 2 dApp for production deployment, there are several optimizations you can implement to improve performance and reduce bundle size.
1. Verify System Requirementsโ
Before deploying to production, ensure you have the correct versions of all dependencies:
# Check versions
node --version # >= v18.17
scarb --version # 2.15.1
snforge --version # 0.55.0
# you typically won't use starknet-devnet in production
Using incompatible versions may cause unexpected issues in production. Make sure to align with the compatible versions specified in Scaffold-Stark 2.
2. Remove Debug Featuresโ
1. Debug Page Removalโ
The debug page is a development tool that should be removed for production builds. You can remove it by:
Delete the debug page and its components:
rm -rf packages/nextjs/app/debug
2. Remove the debug route from your navigationโ
If you've added it manually in any of your components, you can remove the debug route from it.
If you want to keep the debug features for development while removing them from production, you can use environment-based conditional rendering:
{process.env.NODE_ENV === 'development' && (
<Link href="/debug">Debug Contracts</Link>
)}
:::tip[Hint]
## 3. Remove the block explorer pages
Typically this feature is not needed in production since it is just a local devnet explorer. If you want to keep it for development, you can use environment-based conditional rendering:
Delete the block explorer pages and their constituent files:
```bash
rm -rf packages/nextjs/app/blockexplorer # the page
rm -rf packages/nextjs/hooks/blockexplorer # the hooks
rm -rf packages/nextjs/utils/blockExplorer # the utils
```
:::tip[Hint]
If you want to keep the block explorer pages for development while removing them from production, you can use environment-based conditional rendering:
```typescript
{process.env.NODE_ENV === 'development' && (
<Link href="/blockexplorer">Block Explorer</Link>
)}
```
:::tip[Hint]
## 4. Asset optimization
### Image Optimization
Scaffold-Stark 2 comes with pre-configured image optimization in [`next.config.mjs`](https://github.com/Scaffold-Stark/scaffold-stark-2/blob/main/packages/nextjs/next.config.mjs). The configuration includes secure handling of SVGs and specific remote patterns for Starknet-related images.
#### 1. When adding new image sources, extend the existing `remotePatterns` in `next.config.mjs`:
```javascript
images: {
dangerouslyAllowSVG: true,
remotePatterns: [
{
protocol: "https",
hostname: "your-new-domain.com",
pathname: "/**",
},
// existing patterns...
],
}
2. Use the Next.js Image component with the allowed domains:โ
import Image from 'next/image';
export function YourComponent() {
return (
<Image
src="https://identicon.starknet.id/your-image"
alt="Description"
width={400}
height={300}
/>
);
}
Only add domains to remotePatterns that you trust and need for your application. For each additional pattern may increases the potential attack surface of the application.
Additional Build optimizationsโ
Scaffold-Stark 2 includes several build optimizations in next.config.mjs to ensure better production performance:
1. TypeScript and ESLint Error Handling:โ
typescript: {
ignoreBuildErrors: process.env.NEXT_PUBLIC_IGNORE_BUILD_ERROR === "true",
},
eslint: {
ignoreDuringBuilds: process.env.NEXT_PUBLIC_IGNORE_BUILD_ERROR === "true",
},
These settings control how your application handles TypeScript and ESLint errors during the build process:
- When
NEXT_PUBLIC_IGNORE_BUILD_ERRORenvironment variable is set totrue:- TypeScript type checking errors won't stop your build
- ESLint warnings and errors won't prevent deployment
- This is useful when: - You're in rapid development and want to test deployments despite minor type issues - You're dealing with third-party dependencies that have type conflicts - You're migrating a JavaScript project to TypeScript and want to deploy while still fixing type issues
While these settings can help you deploy quickly, it's recommended to fix all TypeScript and ESLint errors before deploying to production. Ignoring these errors might hide potential bugs or issues in your code.
2. Webpack optimization for compatibility:โ
webpack: (config) => {
config.resolve.fallback = { fs: false, net: false, tls: false };
config.externals.push("pino-pretty", "lokijs", "encoding");
return config;
},
This webpack configuration handles some important compatibility issues:
- Fallback Resolution:
config.resolve.fallback = { fs: false, net: false, tls: false };
This configuration tells webpack how to handle Node.js-specific modules in the browser by disabling several Node.js-native modules: the file system module (fs), the network module (net), and the TLS/SSL module (tls). This configuration is necessary because some dependencies might try to use these Node.js modules that don't exist in the browser environment, which could cause compatibility issues. 2. External Dependencies:
config.externals.push("pino-pretty", "lokijs", "encoding");
This configuration marks certain packages as external to prevent them from being bundled with your client-side code. This includes pino-pretty (a logging library formatter), lokijs (an in-memory database), and encoding (a text encoding library). These packages are typically only needed on the server-side and shouldn't be included in the client bundle, which helps reduce the size of your frontend code.
These webpack optimizations help:
- Reduce your bundle size
- Prevent compatibility issues between Node.js and browser environments
- Improve loading performance
- Handle common dependencies that cause build issues
Hint
Setting Up Build Environment Variablesโ
To control these optimizations, you can set up your environment variables:
- For local development(packages/nextjs/.env.local):
# Only use during development
NEXT_PUBLIC_IGNORE_BUILD_ERROR=true
- For production deployment:
# Make sure this is false or unset in production
NEXT_PUBLIC_IGNORE_BUILD_ERROR=false
- During development:
- You can set
NEXT_PUBLIC_IGNORE_BUILD_ERROR=trueto speed up testing - Use this to iterate quickly on features
- Before production:
- Set
NEXT_PUBLIC_IGNORE_BUILD_ERROR=falseor remove it - Fix all TypeScript and ESLint errors
- Test the build locally with production settings
Best Practices
5. Production Environment Setupโ
Production Environment Variablesโ
Ensure your production environment variables are properly set in your deployment platform:
# In packages/nextjs/.env.local
NEXT_PUBLIC_PROVIDER_URL=https://your-provider.example.com/your-api-key/rpc/v0_8
Make sure your RPC provider URL includes the correct version path (v0_8). You can verify the RPC version with this curl command:
# Verify RPC version (should be 0.10.x)
curl -X POST -H "Content-Type: application/json" --data '{
"jsonrpc":"2.0",
"method":"starknet_specVersion",
"id":1
}' https://your-rpc-endpoint
Never commit production environment variables to your repository. Use .env.local for local development and configure environment variables directly in your deployment platform for production.
6. Build Optimizationโ
Next.js Build Configurationโ
Optimize your Next.js build by adding the following to your next.config.mjs:
/** @type {import('next').NextConfig} */
const nextConfig = {
// ... other config
compiler: {
removeConsole: process.env.NODE_ENV === "production",
},
experimental: {
optimizeCss: true,
},
};
7. Production Deployment Checklistโ
Before deploying to production, you can follow the following checklist to make sure you have the most optimum build:
- Removed or conditionally rendered debug packages
- Removed or conditionally rendered block explorer pages
- Configured production environment variables
- Optimized all images and assets
- Run and tested production build locally
- Updated all RPC endpoints to production URLs
- Removed any hardcoded development addresses
- Verified all smart contract integrations
- Tested wallet connections on production networks
Production Build Commandโ
Use yarn build followed by yarn start to test your production build locally before deploying.
# Build the application
yarn build
# Test the production build locally
yarn start
Common Pitfallsโ
- Leaving development RPC endpoints in production
- Not configuring proper environment variables
- Keeping debug routes accessible in production
- Using development contract addresses in production
- Not optimizing images and other assets
- Leaving console.log statements in production code