- Shortcuts Bar: Redesigned layout (Esc/Tab grouped, Space added), unified NAV styling, and implemented consistent Arch Blue branding. - AUR Integration: - Added yay/paru helper toggle with keyboard shortcuts (1/2). - Implemented minimal visual ARCH logo indicator for AUR packages. - Standardized all AUR-related UI elements (checkboxes, badges) to official Arch Blue (#1793d1). - Theme System: Refactored useTheme hook to a global Context Provider for perfect animation sync. - Animations & UI: Enhanced drawer animations (slide-up/down), tooltips, and hover states using GSAP. - Performance: Optimized app filtering with useMemo to prevent re-renders; fixed reconciliation issues. - Fixes: Resolved hydration mismatches and malformed HTML tags. - Docs: Updated README and CONTRIBUTING guidelines. - Refactor: Cleaned up unused code.
12 KiB
Contributing to TuxMate
Thank you for your interest in contributing! This guide ensures high-quality, error-free contributions.
⚠️ Before You Start
Your PR will be rejected if you:
- ❌ Submit unverified package names
- ❌ Use wrong package name casing (e.g.,
firefoxvsMozillaFirefox) - ❌ Put
pacmanpackages inarchwhen they're AUR-only - ❌ Use partial Flatpak IDs instead of full App IDs
- ❌ Forget
--classicfor Snap packages that require it - ❌ Include PPAs or unofficial repos for apt packages
📦 Adding Applications
All applications are defined in src/lib/data.ts.
Mandatory Research Protocol
You MUST verify every package on these official sources before submitting:
| Source | What to Check | URL |
|---|---|---|
| Repology | Global package index (check first!) | https://repology.org/project/[app-name]/versions |
| Arch Linux | Official repos (core, extra) |
archlinux.org/packages |
| AUR | User repos (only if not in official!) | aur.archlinux.org |
| Ubuntu/Debian | Main/Universe repos only, NO PPAs | packages.ubuntu.com / packages.debian.org |
| Fedora | Official packages | packages.fedoraproject.org |
| OpenSUSE | Official packages | software.opensuse.org |
| NixOS | Nix packages | search.nixos.org |
| Flathub | Flatpak apps (get the App ID!) | flathub.org |
| Snapcraft | Snap packages | snapcraft.io |
Entry Structure
{
id: 'app-id', // Unique, lowercase, kebab-case
name: 'App Name', // Official display name
description: 'Short description', // Max ~25 characters
category: 'Category', // Must match valid categories
iconUrl: si('icon-slug', '#color'), // See Icon System section
targets: {
ubuntu: 'exact-package-name', // apt package (official repos ONLY)
debian: 'exact-package-name', // apt package (official repos ONLY)
arch: 'exact-package-name', // pacman OR AUR package name
fedora: 'exact-package-name', // dnf package
opensuse: 'exact-package-name', // zypper package (CASE SENSITIVE!)
nix: 'exact-package-name', // nix package
flatpak: 'com.vendor.AppId', // FULL Flatpak App ID (reverse DNS)
snap: 'snap-name', // Add --classic if needed
},
unavailableReason?: 'Markdown install instructions'
}
⛔ Strict Rules (Read Carefully!)
Package Name Rules
| Rule | ✅ Correct | ❌ Wrong |
|---|---|---|
| Case sensitivity | MozillaFirefox (openSUSE) |
firefox |
| Exact package name | firefox-esr (Debian) |
firefox |
| OpenJDK versions | openjdk-21-jdk (Ubuntu) |
openjdk |
| Arch package | firefox |
firefox-bin (when official exists) |
Arch Linux: arch vs AUR
| Situation | Field to Use | Example |
|---|---|---|
Package in official repos (core/extra) |
arch: 'package' |
arch: 'firefox' |
| Package NOT in official repos | arch: 'package-bin' |
arch: 'brave-bin' |
| NEVER mix both | Use only ONE | — |
How to check:
- Search archlinux.org/packages
- If found → use
archfield - If NOT found → search aur.archlinux.org → use
archfield with AUR package name - Prefer
-binsuffix packages in AUR (pre-built, faster install) - IMPORTANT: If your AUR package name does NOT end in
-bin,-git, or-appimage, you MUST add it toKNOWN_AUR_PACKAGESinsrc/lib/aur.tsso the app knows it's from AUR.
Ubuntu/Debian: Official Repos Only
| ✅ Allowed | ❌ NOT Allowed |
|---|---|
| Main repository packages | PPAs |
| Universe repository packages | Third-party repos |
| Packages on packages.ubuntu.com | Manual .deb downloads |
If a package requires a PPA: Leave the field empty and add install instructions to unavailableReason.
Flatpak: Full App ID Required
| ✅ Correct | ❌ Wrong |
|---|---|
com.spotify.Client |
spotify |
org.mozilla.firefox |
firefox |
app.zen_browser.zen |
zen-browser |
How to find: Go to flathub.org, search the app, copy the full App ID from the app page.
Snap: Classic Confinement
Some snaps require --classic flag. Check snapcraft.io for the app and look for "classic" confinement.
| App Type | Format |
|---|---|
| Regular snap | 'snap-name' |
| Classic confinement | 'snap-name --classic' |
Empty Fields
If a package doesn't exist in a source, leave the field empty (omit it entirely):
// ✅ Correct - Discord not in apt repos
targets: {
arch: 'discord',
flatpak: 'com.discordapp.Discord',
snap: 'discord'
}
// ❌ Wrong - Empty strings clutter the code
targets: {
ubuntu: '',
debian: '',
arch: 'discord',
fedora: '',
opensuse: '',
nix: '',
flatpak: 'com.discordapp.Discord',
snap: 'discord'
}
The unavailableReason Field
Use this to provide helpful installation alternatives when an app isn't available in most package managers.
Format: Markdown with clickable links
// ✅ Good example
unavailableReason: 'Not in official repos. Use [Flatpak](https://flathub.org/apps/com.example.App) or download from [example.com](https://example.com/download).'
// ❌ Bad examples
unavailableReason: 'Not available' // No helpful info
unavailableReason: 'Download from website' // No link provided
Valid Categories
Use exactly one of these:
Web Browsers • Communication • Dev: Languages • Dev: Editors • Dev: Tools
Terminal • CLI Tools • Media • Creative • Gaming • Office
VPN & Network • Security • File Sharing • System
🎨 Icon System
TuxMate uses the Iconify API for icons. Icon helpers are defined in src/lib/data.ts.
Helper Functions
| Function | Use Case | Example |
|---|---|---|
si('slug', '#color') |
Simple Icons (brands) | si('firefox', '#FF7139') |
lo('slug') |
Colorful logos | lo('chrome') |
mdi('slug', '#color') |
Material Design icons | mdi('console', '#57F287') |
dev('slug') |
Devicon (dev tools) | dev('vscode') |
sk('slug') |
Skill Icons (colorful) | sk('react') |
vs('slug') |
VS Code file icons | vs('file-type-shell') |
Finding Icon Slugs
| Source | URL | Notes |
|---|---|---|
| Simple Icons | simpleicons.org | Use lowercase slug, add hex color |
| Material Design | pictogrammers.com/library/mdi | Use icon name |
| Iconify Search | icon-sets.iconify.design | Search all sets |
| Fallback | — | Use mdi('application', '#color') |
Icon Requirements
- ✅ Must be recognizable at 24×24px
- ✅ Use official brand colors - click icon to copy hex
- ✅ Monochrome icons (si, mdi) require a color parameter
- ✅ Colorful icons (lo, sk, vs) don't need color
- ❌ Don't use blurry or low-quality external URLs
🔀 Pull Request Checklist
Before submitting, verify ALL of these:
Package Verification
- Checked Repology for global package availability
- Verified exact package names on each distro's official package search
- Confirmed case sensitivity (especially openSUSE:
MozillaFirefox,MozillaThunderbird) - Arch packages confirmed in official repos OR AUR
- Ubuntu/Debian packages are in Main/Universe only (no PPAs)
- Flatpak uses full App ID from Flathub
- Snap packages checked for
--classicrequirement
Code Quality
- Tested locally with
npm run dev - Production build passes:
npm run build - Lint passes:
npm run lint - Unit tests pass:
npm run test - Apps added in alphabetical order within their category
- Icons display correctly at small sizes
📝 PR Description Template
Include this in your PR description:
## Apps Added/Modified
- App Name 1
- App Name 2
## Verification URLs
Paste the direct links to the package pages you checked:
- **Repology**: [link]
- **Arch/AUR**: [link]
- **Ubuntu/Debian**: [link]
- **Fedora**: [link]
- **OpenSUSE**: [link]
- **NixOS**: [link]
- **Flathub**: [link]
- **Snapcraft**: [link]
## Checklist
- [ ] All package names verified on official sources
- [ ] Tested locally with `npm run dev`
- [ ] Build passes: `npm run build`
💻 Development Workflow
Setup
git clone https://github.com/abusoww/tuxmate.git
cd tuxmate
npm install
npm run dev
Before Committing
npm run lint # Check for errors
npm run lint -- --fix # Auto-fix issues
npm run test # Run unit tests
npm run build # Verify production build
Branch Naming
feature/add-app-name
feature/add-distro-name
fix/description-of-fix
docs/update-readme
Commit Format
type: short description
- Details if needed
- Fixes #123
Types: feat fix docs style refactor test chore
🐧 Adding Distributions
Distributions are defined in src/lib/data.ts.
Distro Structure
{
id: 'distro-id',
name: 'Display Name',
iconUrl: si('distro-slug', '#color'),
color: '#HexColor',
installPrefix: 'sudo pkg install -y'
}
After Adding a Distro
- Add the distro ID to the
DistroIdtype insrc/lib/data.ts - Create a new script generator file:
src/lib/scripts/[distro].ts - Export the generator from
src/lib/scripts/index.ts - Add the case in
src/lib/generateInstallScript.ts(both functions) - Handle distro-specific logic (repo setup, package detection, etc.)
- Add
targets.[distro]entries to relevant apps indata.ts
⚙️ Script Generation
Script generation is modular. Each distro has its own generator:
src/lib/
├── generateInstallScript.ts # Main entry point
├── aur.ts # AUR package detection
└── scripts/
├── index.ts # Exports all generators
├── shared.ts # Colors, progress bars, utilities
├── arch.ts # Arch + AUR (yay)
├── debian.ts # Debian apt
├── ubuntu.ts # Ubuntu apt + PPA handling
├── fedora.ts # Fedora dnf + RPM Fusion
├── opensuse.ts # openSUSE zypper
├── nix.ts # Nix package manager
├── flatpak.ts # Flatpak (parallel install)
└── snap.ts # Snap packages
Key Features to Maintain
- Package detection - Skip already-installed packages
- AUR handling - Auto-install
yayhelper (seeaur.tsfor patterns) - RPM Fusion - Auto-enable for Fedora when needed
- Parallel installation - Flatpak concurrent installs
- Network retry - Exponential backoff for failures
- Progress bars - ETA with colored output
- Shell escaping - Security against injection (see
escapeShellString()inshared.ts)
Testing Script Changes
# Run unit tests (shell escaping, AUR detection)
npm run test
# Generate and test a script
npm run dev
# Select packages → Copy script → Test in VM/container
# Quick testing with Docker
docker run -it archlinux bash
docker run -it ubuntu bash
🐛 Reporting Issues
Bug Reports — Include:
- Browser & OS (e.g., Firefox 120 on Arch Linux)
- Steps to reproduce (numbered list)
- Expected vs actual behavior
- Console errors (F12 → Console tab)
- Screenshots if UI-related
Feature Requests — Include:
- Use case and why it's needed
- Proposed solution
- Alternatives considered
❓ Questions?
Open a Discussion or create an Issue.