This document describes the standard structure and conventions for packages in this monorepo.
All TypeScript/JavaScript packages should follow this structure:
packages/package-name/
├── src/
│ ├── index.ts # Main entry point
│ ├── launcher.ts # Launcher (if service)
│ ├── service.ts # Service (if service)
│ ├── types.ts # Type definitions
│ └── utils/ # Utility functions
│ └── logger.ts
├── test/
│ ├── launcher.spec.ts # Launcher tests
│ ├── service.spec.ts # Service tests
│ └── utils.spec.ts # Utility tests
├── dist/
│ ├── esm/ # ESM build output
│ │ ├── index.js
│ │ └── index.d.ts
│ └── cjs/ # CJS build output
│ ├── index.js
│ └── index.d.ts
├── package.json # Package manifest
├── tsconfig.json # TypeScript config (extends base)
├── tsconfig.cjs.json # TypeScript CJS config
├── vitest.config.ts # Vitest config
└── README.md # Package documentation
Tauri plugin packages follow a different structure:
packages/tauri-plugin/
├── src/
│ ├── lib.rs # Plugin entry point
│ ├── commands.rs # Tauri command implementations
│ ├── models.rs # Data models
│ ├── error.rs # Error types
│ ├── mock_store.rs # Mock storage implementation
│ ├── desktop.rs # Desktop-specific code
│ └── mobile.rs # Mobile-specific code
├── guest-js/ # Frontend JavaScript/TypeScript
│ ├── index.ts # Frontend API implementation
│ └── index.d.ts # TypeScript definitions
├── permissions/ # Tauri v2 permissions
│ ├── default.toml # Default permissions
│ └── autogenerated/ # Auto-generated permission files
├── build.rs # Build script
├── Cargo.toml # Rust crate manifest
├── package.json # NPM package manifest (for frontend)
├── tsconfig.json # TypeScript config for frontend
└── README.md # Package documentation
All packages use the @wdio/ scope:
@wdio/electron-service- Electron WDIO service@wdio/tauri-service- Tauri WDIO service@wdio/electron-cdp-bridge- Chrome DevTools Protocol bridge@wdio/native-utils- Cross-platform utilities@wdio/native-types- Shared TypeScript type definitions@wdio/native-spy- Spy utilities for mocking@wdio/tauri-plugin- Tauri v2 plugin (Rust + JS)@wdio/bundler- Build tooling
{
"name": "@wdio/package-name",
"version": "1.0.0",
"type": "module",
"description": "Package description",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/cjs/index.d.ts",
"default": "./dist/cjs/index.js"
}
}
},
"engines": {
"node": "^18.12.0 || ^20.0.0"
},
"scripts": {
"build": "pnpm build:esm && pnpm build:cjs",
"build:esm": "tsc -p tsconfig.json",
"build:cjs": "tsc -p tsconfig.cjs.json",
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"lint": "biome check .",
"typecheck": "tsc --noEmit",
"clean": "shx rm -rf dist coverage .turbo"
},
"dependencies": {},
"devDependencies": {
"@types/node": "catalog:default",
"@vitest/coverage-v8": "catalog:default",
"typescript": "catalog:default",
"vitest": "catalog:default"
},
"peerDependencies": {
"webdriverio": "^9.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/webdriverio/desktop-mobile.git",
"directory": "packages/package-name"
},
"license": "MIT"
}Each package should have two TypeScript configurations:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist/esm",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}{
"extends": "../../tsconfig.base.cjs.json",
"compilerOptions": {
"outDir": "./dist/cjs",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test"]
}import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
include: ['test/**/*.spec.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
thresholds: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
},
},
},
});Packages should build to both ESM and CJS formats:
# Build both formats
pnpm build
# Build ESM only
pnpm build:esm
# Build CJS only
pnpm build:cjsAll packages must maintain 80%+ test coverage:
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverageFor internal dependencies, use the workspace: protocol:
{
"dependencies": {
"@wdio/native-utils": "workspace:*"
}
}For common external dependencies, use the catalog reference:
{
"devDependencies": {
"typescript": "catalog:default",
"vitest": "catalog:default"
}
}Each package should have a comprehensive README with:
- Description - What the package does
- Installation - How to install
- Usage - Basic usage examples
- API - API documentation
- Configuration - Configuration options
- Examples - Code examples
- Contributing - Contribution guidelines
- License - License information
Packages are published from the monorepo using Turborepo:
# Publish all packages
pnpm turbo release- Keep packages focused - Each package should have a single responsibility
- Minimize dependencies - Only add necessary dependencies
- Write comprehensive tests - Maintain 80%+ coverage
- Document public APIs - Use JSDoc comments
- Follow TypeScript strict mode - Enable strict type checking
- Use semantic versioning - Follow semver for versions
- Avoid breaking changes - Maintain backward compatibility when possible