This guide covers building TryDevUtils for production across all supported platforms: web app, desktop app, and Chrome extension.
Build overview
TryDevUtils uses Vite as its build tool with different configurations for each platform:
- Web: Standard Vite build with PWA support
- Desktop: Tauri build with platform-specific bundles
- Extension: Custom Vite build with extension-specific entry points
Web app build
Build the web app for production deployment:
Build output
The production build creates optimized files in dist/:
dist/
├── index.html
├── assets/
│ ├── index-[hash].js # Main bundle
│ ├── vendor-[hash].js # React, React Router
│ ├── ui-[hash].js # Radix UI components
│ ├── utils-[hash].js # Utilities (date-fns, etc.)
│ └── index-[hash].css # Styles
├── manifest.webmanifest # PWA manifest
└── sw.js # Service worker (PWA)
Build optimizations
The Vite configuration applies several optimizations:
Code minification
// vite.config.ts
minify: "terser",
terserOptions: {
compress: {
drop_console: true, // Remove console.log
drop_debugger: true, // Remove debugger
pure_funcs: [ // Remove specific functions
"console.log",
"console.info",
"console.debug",
"console.warn",
],
passes: 2, // Two minification passes
},
}
Code splitting
Automatic chunk splitting reduces initial load time:
vendor.js: React, React DOM, React Router
ui.js: Radix UI components
utils.js: Date utilities, YAML parser, diff library
PWA generation
Production builds include Progressive Web App features:
- Service worker for offline support
- Web manifest for installability
- Cached assets for fast loading
PWA features are only enabled for production web builds, not desktop or extension builds.
Desktop app build
Build the Tauri desktop app for your platform:
Build artifacts
The desktop build creates platform-specific installers in src-tauri/target/release/bundle/:
src-tauri/target/release/bundle/
├── dmg/
│ └── TryDevUtils_0.1.4_aarch64.dmg # Apple Silicon
│ └── TryDevUtils_0.1.4_x86_64.dmg # Intel
└── macos/
└── TryDevUtils.app
Distribution: Upload .dmg files to GitHub Releases or your website.src-tauri/target/release/bundle/
├── msi/
│ └── TryDevUtils_0.1.4_x64_en-US.msi # MSI installer
└── nsis/
└── TryDevUtils_0.1.4_x64-setup.exe # NSIS installer
Distribution: Provide both MSI (enterprise) and NSIS (consumer) installers.src-tauri/target/release/bundle/
├── deb/
│ └── trydevutils_0.1.4_amd64.deb # Debian package
├── rpm/
│ └── trydevutils-0.1.4-1.x86_64.rpm # RPM package
└── appimage/
└── trydevutils_0.1.4_amd64.AppImage # AppImage
Distribution: AppImage is most portable. Provide deb/rpm for package managers.
The GitHub Actions workflow builds for all platforms:
# .github/workflows/release-desktop.yml
matrix:
include:
- platform: macos-latest
target: aarch64-apple-darwin
- platform: macos-latest
target: x86_64-apple-darwin
- platform: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- platform: windows-latest
target: x86_64-pc-windows-msvc
Version sync
The sync:version script ensures version consistency:
This syncs the version from package.json to:
src-tauri/tauri.conf.json
extension/manifest.json
Always run sync:version before building desktop or extension releases.
Chrome extension build
Build the Chrome extension:
Build the extension bundle
This builds to dist-extension/ with extension-specific configuration. Prepare for distribution
npm run extension:prepare
This:
- Builds the extension
- Copies
manifest.json to dist-extension/
- Copies icons to
dist-extension/icons/
- Removes web-specific files (like
_redirects)
Create distribution package
cd dist-extension
zip -r ../TryDevUtils_extension_v0.1.4.zip .
Extension build differences
The extension build differs from the web build:
// vite.config.ts
const isExtension = mode === "extension";
build: {
outDir: isExtension ? "dist-extension" : "dist",
rollupOptions: {
input: isExtension
? {
index: "extension/index.html",
background: "extension/background.ts",
}
: undefined,
output: {
entryFileNames: "[name].js", // No hashes for extensions
manualChunks: isExtension ? undefined : {...}, // No splitting
},
},
}
Extensions don’t use code splitting or hashed filenames because Chrome’s extension loader expects fixed entry points.
CI builds
The CI pipeline runs automated builds and tests:
This command:
- Runs
vite build to build the web app
- Installs Playwright browsers
- Runs
npm run test:ci to verify the build
GitHub Actions workflow
# .github/workflows/ci-vercel.yml
jobs:
build-test:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Build and run tests
run: npm run build:ci
Build configuration
Vite configuration
Key settings in vite.config.ts:
export default defineConfig(({ mode }) => {
const isExtension = mode === "extension";
const isTauri = !!process.env.TAURI_ENV_PLATFORM;
const isWebProduction = mode === "production" && !isTauri;
return {
server: {
host: host || "::",
port: host ? 1420 : 8080,
},
build: {
outDir: isExtension ? "dist-extension" : "dist",
minify: "terser",
sourcemap: false,
cssMinify: true,
cssCodeSplit: true,
chunkSizeWarningLimit: 1000,
},
};
});
TypeScript configuration
Type checking is enforced during builds:
npm run check # tsc && vite build
Build troubleshooting
Build fails with type errors
Run type checking separately to see full errors:
Out of memory during build
Increase Node.js memory limit:
NODE_OPTIONS="--max-old-space-size=4096" npm run build
Tauri build fails on Linux
Install required system dependencies:
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libappindicator3-dev \
librsvg2-dev \
patchelf \
libgtk-3-dev \
libsoup-3.0-dev
Extension build creates wrong files
Ensure you’re using the extension-specific command:
npm run extension:prepare # Not just build:extension
Production checklist
Before deploying to production:
Next steps