@funish/basis
v0.1.2
Published
A unified development toolkit with CLI for package management, versioning, publishing, linting, and git hooks management for JavaScript/TypeScript projects.
Downloads
148
Maintainers
Readme
@funish/basis
A unified development toolkit with CLI for package management, versioning, publishing, linting, and git hooks management for JavaScript/TypeScript projects.
🧑💻 Contributing? See the monorepo documentation for development setup and contribution guidelines.
What is Basis?
Basis is your unified development toolkit for modern JavaScript/TypeScript projects. Instead of juggling multiple CLI tools, Basis provides a single interface for all your development workflow needs.
Features
- 🎯 Unified CLI: One command interface for all development tasks
- 📦 Package Management: Install, add, remove dependencies with auto-detected package manager (npm, yarn, pnpm, bun, deno)
- 🏷️ Version Management: Semantic versioning with automated git tagging and releases
- 🚀 Publishing: Multi-tag publishing strategy with edge version tracking
- 🔧 Tool Agnostic Linting: Not tied to specific linters - use ESLint, Oxlint, Biome, or any tool you prefer
- 🛠️ Auto-fix Issues: Automatically fix dependencies, structure, and documentation issues
- 🪝 Smart Git Hooks: Automatic git repository initialization and hook management
- 💻 Modern Stack: Built on the unjs ecosystem (citty, consola, c12, nypm, semver)
- 💪 TypeScript First: Full TypeScript support with excellent DX
- 📚 Smart Defaults: Best practices built-in, fully customizable
- 🔧 Single Configuration: One config file for all functionality
Quick Start
Recommended Installation (Global with pnpm)
# Install globally with pnpm (recommended)
pnpm add -g @funish/basis
# Or install globally with npm
npm install -g @funish/basis
# Verify installation
basis --versionAlternative Installation Methods
# Install in your project with pnpm
pnpm add -D @funish/basis
# Or with npm
npm install -D @funish/basis
# Or use directly without installation
npx @funish/basis initInitialize in Existing Project
cd your-existing-project
basis init
# Interactive setup will ask you to:
# 📁 Choose config format (.ts/.mjs/.cjs) - auto-detected based on your project
# 🔧 Optionally setup Git hooks and configuration
# Your project now has:
# ✅ Configuration file with Git hooks that adapt to your package manager
# ✅ Git hooks setup (if selected during init)
# ✅ Tool-agnostic linting workflow
# ✅ Package management through unified CLI
# ✅ Version management with semantic versioning
# ✅ Publishing workflow with multi-tag strategyCLI Commands
Package Management
# Install dependencies (auto-detects package manager)
basis install # or basis i
basis install --frozen-lockfile
# Add dependencies
basis add lodash # Add to dependencies
basis add -D typescript # Add to devDependencies
basis add --workspace app react # Add to specific workspace
basis add -g @funish/basis # Install globally
# Remove dependencies
basis remove lodash # or basis rm / basis uninstall
basis remove -D typescript
# Run scripts
basis run build # Run package.json scripts
basis run test --silentVersion Management
# Semantic version increments
basis version patch # 1.0.0 → 1.0.1
basis version minor # 1.0.0 → 1.1.0
basis version major # 1.0.0 → 2.0.0
# Prerelease versions
basis version --prerelease # 1.0.0 → 1.0.1-edge.0
basis version --prerelease --preid beta # 1.0.0 → 1.0.1-beta.0
# Specific version
basis version 2.0.0
# Custom commit message
basis version patch --message "fix: critical bug"Publishing
# Standard publishing (to edge tag)
basis publish
# Stable release (to latest + edge tags)
basis publish --stable
# Custom tag publishing (to custom + edge tags)
basis publish --tag beta
basis publish --tag alpha
# Dry run
basis publish --dry-run
# Skip build/tests
basis publish --skip-build --skip-testsLinting
# Lint staged files
basis lint --staged
# Run project-wide linting
basis lint --project
# Check dependencies
basis lint --deps
# Check project structure
basis lint --structure
# Check documentation
basis lint --docs
# Run all lint checks
basis lint --all
# Auto-fix issues (can be combined with any check)
basis lint --deps --fix # Check and fix dependency issues
basis lint --structure --fix # Check and fix structure issues
basis lint --docs --fix # Check and fix documentation issues
basis lint --all --fix # Check and fix all issues
basis lint --staged --fix # Note: --fix only works with --deps, --structure, --docs, --allAuto-fix Features
The --fix flag enables automatic fixing of common issues:
🔧 Dependency Fixes:
- Remove blocked packages: Automatically uninstall packages listed in
blockedPackages - Update outdated dependencies: Use package manager's update command to fix outdated packages
- Fix security vulnerabilities: Attempt to fix security issues using
npm audit fixor equivalent
📁 Structure Fixes:
- Create missing files: Generate empty files for items in
requiredFiles - Create missing directories: Generate directories for items in
requiredDirs
📝 Documentation Fixes:
- Generate README.md: Create an empty README.md if missing
- Generate CHANGELOG.md: Create an empty CHANGELOG.md if missing
Configuration: All fix behaviors are controlled by the lint.fix configuration in your basis.config.ts:
export default defineBasisConfig({
lint: {
fix: {
dependencies: {
removeBlocked: true, // Enable automatic removal of blocked packages
updateOutdated: false, // Disable automatic updates (manual control)
fixSecurity: true, // Enable security fix attempts
},
structure: {
createMissingFiles: true, // Enable file creation
createMissingDirs: true, // Enable directory creation
},
docs: {
generateReadme: true, // Enable README generation
generateChangelog: false, // Disable CHANGELOG generation
},
},
},
});Git Hooks Management
# Setup git configuration and hooks
basis git setup
# Setup git configuration only
basis git config
# Setup git hooks only
basis git hooks
# Remove git hooks
basis git remove # Remove all basis-managed hooks
basis git remove pre-commit # Remove specific hook
basis git remove --update-config # Remove hooks AND config from basis.config.ts
# Reset git configuration
basis git reset # Reset config (keep user info)
basis git reset --no-keep-user # Reset config (remove user info)
basis git reset --update-config # Reset config AND remove from basis.config.ts
# Initialize git repository with basis configuration
basis git init
# Validate commit message
basis git --lint-commitProject Management
# Initialize configuration
basis init # Initialize basis configuration (interactive)
basis init --force # Overwrite existing configuration
basis init --skip-git-check # Skip git directory check
basis init --skip-install # Skip dependency installation
# Interactive setup will:
# 1. Auto-detect recommended config format (.ts/.mjs/.cjs)
# 2. Ask you to choose your preferred format
# 3. Offer to setup Git hooks and configuration
# Configuration
basis config # Show current configuration
basis config --json # Output configuration as JSON
basis config --path # Show configuration file path
# Help
basis --help # Show help
basis <command> --help # Show command-specific helpConfiguration
Basis uses a single configuration file for all its features. The basis init command creates a configuration file with customized Git hooks in your preferred format:
// basis.config.ts (TypeScript) or basis.config.mjs (ES Module)
import { defineBasisConfig } from "@funish/basis";
export default defineBasisConfig({
// Configure your project here
// See: https://github.com/funish/basis/tree/main/packages/basis#configuration
git: {
hooks: {
"pre-commit": "pnpmbasis lint --staged", // Auto-adapts to your package manager
"commit-msg": "pnpmbasis git --lint-commit",
},
},
});// basis.config.cjs (CommonJS)
const { defineBasisConfig } = require("@funish/basis");
module.exports = defineBasisConfig({
// Configure your project here
// See: https://github.com/funish/basis/tree/main/packages/basis#configuration
git: {
hooks: {
"pre-commit": "npx basis lint --staged", // Auto-adapts to your package manager
"commit-msg": "npx basis git --lint-commit",
},
},
});💡 Configuration: The generated config file only shows the Git hooks that are customized for your package manager. All other configuration options use smart defaults and can be added as needed.
Full Configuration Example
Here's a complete configuration with all available options:
// basis.config.ts
import { defineBasisConfig } from "@funish/basis";
export default defineBasisConfig({
// Linting configuration
lint: {
// Staged files linting patterns
staged: {
"*.{ts,tsx,js,jsx}": "pnpm eslint --fix",
"*.{json,md,yml,yaml}": "pnpm prettier --write",
"*.vue": "pnpm vue-tsc --noEmit && pnpm eslint --fix",
},
// Project-wide linting commands
project: {
typecheck: "pnpm tsc --noEmit",
"format-check": "pnpm prettier --check .",
},
// Auto-fix configuration
fix: {
// Dependency fix options
dependencies: {
removeBlocked: true, // Auto-remove blocked packages
updateOutdated: true, // Auto-update outdated dependencies
fixSecurity: true, // Auto-fix security vulnerabilities
},
// Structure fix options
structure: {
createMissingFiles: true, // Auto-create missing required files
createMissingDirs: true, // Auto-create missing required directories
},
// Documentation fix options
docs: {
generateReadme: true, // Auto-create README.md if missing
generateChangelog: true, // Auto-create CHANGELOG.md if missing
},
},
},
// Git configuration
git: {
// Hook commands
hooks: {
"pre-commit": "pnpmbasis lint --staged",
"commit-msg": "pnpmbasis git --lint-commit",
},
// Commit message validation
commitMsg: {
types: [
"feat",
"fix",
"docs",
"style",
"refactor",
"perf",
"test",
"build",
"ci",
"chore",
],
maxLength: 72,
minLength: 10,
scopeRequired: false,
allowedScopes: ["api", "ui", "core"],
},
// Options
autoInitGit: true, // Auto-initialize git repo if not found
skipGitCheck: false, // Skip git command availability check
force: false, // Force operation even if git unavailable
},
// Version management configuration
version: {
tagPrefix: "v", // Git tag prefix
autoCommit: true, // Auto commit version changes
autoTag: true, // Auto create git tag
autoPush: false, // Manual push control
prereleaseId: "edge", // Default prerelease identifier
commitMessage: "chore: release v{version}",
},
// Publishing configuration
publish: {
defaultTag: "edge", // Always published tag
stableTag: "latest", // Stable release tag
access: "public", // Package access level
registry: "https://registry.npmjs.org/",
buildCommand: "pnpm build", // Build before publish
testCommand: "pnpm test", // Test before publish
checkGitClean: true, // Check git status before publish
checkTests: true, // Run tests before publish
autoGitPush: true, // Push after publish
createGitTag: true, // Create git tag after publish
},
});Publishing Strategy
Basis implements an intelligent multi-tag publishing strategy:
Tag Types
edge: Always points to the latest published version (any type)latest: Points to stable releases- Prerelease Tags:
alpha,beta,rcversions get their own tags - Custom Tags: Flexible tagging for different release channels
Examples
# Version 1.0.0 (stable)
basis publish --stable
# → Published to: latest + edge
# Version 1.1.0-beta.1 (prerelease)
basis publish
# → Published to: beta + edge
# Version 1.2.0 (custom workflow)
basis publish --tag canary
# → Published to: canary + edgeInstallation Examples
# Install stable version
pnpm add @funish/basis # Gets latest tag
# Install edge version (latest published)
pnpm add @funish/basis@edge
# Install prerelease
pnpm add @funish/basis@beta
# Install specific version
pnpm add @funish/[email protected]Core Concepts
🎯 Unified CLI
Single command interface for package management, versioning, publishing, linting, and git hooks. No more switching between different tools.
📦 Auto-Detected Package Manager
Basis automatically detects your preferred package manager (npm, yarn, pnpm, bun, deno) and uses the appropriate commands, powered by nypm.
🏷️ Semantic Versioning
Built-in semantic versioning support using the standard semver package, with automated git tagging and commit generation.
🔧 Tool Agnostic
Basis doesn't force specific tools. Use ESLint, Oxlint, Biome, or any other linter. Basis orchestrates your existing tools, doesn't replace them.
📦 Modern Foundations
Built on the unjs ecosystem, leveraging proven tools like citty, consola, c12, nypm, and semver for maximum reliability and performance.
Integration
Basis integrates seamlessly with:
- Package Managers: npm, yarn, pnpm, bun, deno (auto-detected)
- Linters: ESLint, Oxlint, Biome, Prettier, StyleLint
- Git: Works with any git workflow and hosting provider
- CI/CD: GitHub Actions, GitLab CI, Jenkins
- Frameworks: React, Vue, Angular, Next.js, Nuxt, SvelteKit
Why Choose Basis?
Instead of juggling multiple tools:
npm install package # Package management
yarn version patch # Version management
npm publish --tag beta # Publishing
npx lint-staged # Linting
git config --global ... # Git configurationUse one unified command:
basis add package # Unified package management
basis version patch # Unified version management
basis publish --tag beta # Unified publishing
basis lint --staged # Unified linting
basis git setup # Unified git setupAPI
import {
createBasis,
defineBasisConfig,
// Import module functions directly for maximum flexibility
init,
setupGit,
lintAll,
updatePackageVersion,
publishPackage,
} from "@funish/basis";
// Programmatic usage with Basis class (for config caching and workflows)
const basis = createBasis(process.cwd());
// High-level workflows
await basis.setup({ force: false, skipGitCheck: false, skipInstall: false }); // init + git setup
await basis.release({ patch: true }, { stable: true }); // lint + version + publish
// Configuration management
const config = await basis.getConfig(); // Cached config loading
await basis.reloadConfig(); // Force reload
basis.setCwd("/different/path"); // Change working directory
// Or use module functions directly for more control
const cwd = process.cwd();
await init(cwd, { force: true });
await setupGit(cwd);
await lintAll(cwd);
await updatePackageVersion(cwd, { patch: true });
await publishPackage(cwd, { stable: true });