8.8 KiB
Mue Development Guide
Mue is a fast, open-source new tab page browser extension for Chrome, Firefox, and Safari.
Tech Stack
Core Technologies
- React 19 - Modern hooks and functional components only
- Vite 7 - Build tool with SWC for fast compilation
- Bun - Package manager and JavaScript runtime (>= 1.3.0)
- SCSS - Styling with modern compiler API
- Browser Extension (Manifest V3) - Multi-browser support (Chrome, Firefox, Safari)
Key Libraries
- @dnd-kit - Drag and drop functionality for widgets
- @eartharoid/i18n - Internationalization with multiple locales
- @sentry/react - Error tracking and monitoring
- react-modal - Accessible modal dialogs
- react-toastify - Toast notifications
- IndexedDB & localStorage - Client-side data persistence
- Vite path aliases - Imports use
@/,components/,hooks/,utils/, etc.
Development Tools
- ESLint - JavaScript/JSX linting with React plugin
- Stylelint - SCSS/CSS linting
- Prettier - Code formatting
- Commitlint - Conventional commit enforcement
- Husky - Git hooks for pre-commit checks
Project Structure
src/
├── components/ # Reusable UI components
├── features/ # Feature-specific components (quote, greeting, weather, etc.)
├── contexts/ # React Context providers for shared state
├── hooks/ # Custom React hooks
├── utils/ # Utility functions and helpers
├── lib/ # Third-party library wrappers
├── i18n/ # Internationalization and locale files
├── scss/ # Global styles, variables, and mixins
├── config/ # Configuration files
└── assets/ # Static assets (icons, images)
Development Rules
1. Translation Files
en_GB.json is the base translation file.
When updating translations:
- Edit
src/i18n/locales/en_GB.jsonfirst - Run
bun run translationsto sync changes to all locales - This ensures formatting remains consistent across all language files
Available translation scripts:
bun run translations- Sync all locale files with en_GBbun run translations:percentages- Update completion percentagesbun run translations:unused- Find unused translation keys
2. Branch Strategy
Use the three-branch workflow:
dev- Active development (target for all PRs)beta- Release candidates for testingmain- Production/stable releases
Always create PRs targeting the dev branch.
3. Commit Messages
Follow conventional commits format:
feat:- New featuresfix:- Bug fixeschore:- Maintenance tasksdocs:- Documentation changesrefactor:- Code refactoringtest:- Test-related changesstyle:- Code style changes (formatting, etc.)
Commitlint will enforce this in pre-commit hooks.
4. Code Style & Quality
Before committing:
bun run lint:fix # Auto-fix ESLint and Stylelint issues
bun run pretty # Format code with Prettier
Linting rules:
- Follow ESLint configuration in
eslint.config.js - SCSS follows Stylelint standard SCSS rules
- Husky pre-commit hooks will block commits with linting errors
5. Commenting
Do not add comments to the codebase. Keep code clean and self-explanatory. Use descriptive variable/function names instead of comments.
6. Emojis
Do not use emojis in code strings. Avoid text emojis in console logs, placeholders, or any code strings.
Exception: User-facing toast notifications may include emojis for visual feedback.
// Bad - emojis in console logs
console.log('🔨 Building Chrome extension...');
console.log('✅ Build complete!');
// Good - no emojis
console.log('Building Chrome extension...');
console.log('Build complete!');
// Exception - toast notifications are allowed
toast(`🏆 ${getMessage('achievement_unlocked', { name })}`);
7. Naming Conventions
Keep variable and function names concise. Avoid verbose redundant prefixes like "is" in state variables.
// Good - concise and clear
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [refreshing, setRefreshing] = useState(false);
// Bad - unnecessarily verbose
const [isOpen, setIsOpen] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [isRefreshing, setIsRefreshing] = useState(false);
Exceptions:
- Use "is" prefix for boolean functions/methods that return a value:
isValid(),isAuthenticated() - Use "has" prefix for boolean properties:
hasPermission,hasError
8. Package Manager
Always use Bun (not npm or yarn):
bun install # Install dependencies
bun run dev # Start dev server
bun run build # Production build
9. Build Targets
The project builds for multiple browsers:
- Chrome/Edge (Chromium)
- Firefox
- Safari (via Xcode)
Test changes across all targets when modifying:
- Core functionality
- Manifest files (
manifest/chrome.json,manifest/firefox.json) - Browser-specific APIs
Build outputs:
dist/- Vite bundled outputbuild/chrome/- Chrome extensionbuild/firefox/- Firefox extensionsafari/Mue Extension/Resources/- Safari extension
10. State Management
- Persistent settings - Use
localStoragevia custom hooks - Shared state - Use React Context (see
src/contexts/) - Component state - Use
useState,useReducerfor local state - Custom hooks - Create hooks for reusable stateful logic
11. Styling Conventions
SCSS files are organized in src/scss/:
_variables.scss- Color palette, breakpoints, sizes_mixins.scss- Reusable style mixins- Component styles - Co-located in feature/component folders
Use existing variables and mixins for consistency.
12. Development Server
bun run dev # Local development with HMR at localhost
bun run dev:host # Expose on network for testing on other devices
Hot Module Replacement (HMR) is enabled for fast development.
13. Path Aliases
Use configured path aliases instead of relative imports:
// Good
import Button from 'components/Button';
import { useLocalStorageState } from 'hooks/useLocalStorageState';
import { getWeather } from 'utils/api';
// Avoid
import Button from '../../../components/Button';
Available aliases: @/, components/, contexts/, hooks/, assets/, config/, features/, lib/, scss/, translations/, utils/
14. Error Handling
- Sentry is integrated for error tracking
- Use
ErrorBoundarycomponent for React error boundaries - Handle async errors gracefully with try/catch
- Show user-friendly error messages via
react-toastify
15. Browser Extension Best Practices
- Use Manifest V3 APIs (not deprecated V2 APIs)
- Test extension loading/unloading
- Handle permissions properly
- Use
background.jsfor background tasks - Store data in
localStorageorIndexedDB, not sync storage - Ensure cross-browser compatibility (check MDN for API support)
16. Internationalization (i18n)
All user-visible strings MUST be integrated with i18n. Never hardcode user-facing text.
// Bad - hardcoded strings
<button>Save Settings</button>
toast('Settings saved successfully!');
placeholder="Enter your name"
// Good - using i18n
<button>{getMessage('settings.save')}</button>
toast(getMessage('settings.saved_successfully'));
placeholder={getMessage('user.name_placeholder')}
- Use
@eartharoid/i18nfor all translations - Access translations via the i18n context
- Add new keys to
en_GB.jsonfirst, then runbun run translations - Test with multiple locales to ensure proper rendering
- Support RTL languages where applicable
- Console logs and developer-facing messages do not need i18n
17. Performance
- Lazy load components where appropriate
- Optimize images (use modern formats like WebP)
- Minimize bundle size (check Vite build output)
- Use
useMemoanduseCallbackjudiciously (only when needed) - Profile performance with React DevTools
Common Tasks
Adding a New Feature
- Create feature folder in
src/features/ - Add components, hooks, and styles
- Update translations in
en_GB.json - Run
bun run translationsto sync locales - Add tests if applicable
- Run
bun run lint:fixandbun run pretty - Commit with conventional commit message
- Create PR targeting
devbranch
Debugging
- Use React DevTools for component inspection
- Check browser console for errors
- Use Sentry for production error tracking
- Test in all supported browsers
Testing on Browsers
- Run
bun run build - Load unpacked extension from
build/chrome/orbuild/firefox/ - For Safari, open Xcode project and build from there
Resources
- Repository: https://github.com/mue/mue
- Homepage: https://muetab.com
- Bug Reports: https://github.com/mue/mue/issues