Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
connorads avatar

Better Auth Best Practices

  • 65 installs
  • 15 repo stars
  • Updated August 1, 2026
  • connorads/dotfiles

Helps with ai & agent building tasks.

About

better-auth-best-practices is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.

  • better-auth-best-practices
  • AI & Agent Building
  • AI-coding skill

Better Auth Best Practices by the numbers

  • 65 all-time installs (skills.sh)
  • Ranked #5,943 of 16,556 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/connorads/dotfiles --skill better-auth-best-practices

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs65
repo stars15
Last updatedAugust 1, 2026
Repositoryconnorads/dotfiles

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

hk — Git Hook Manager

hk by jdx runs linters and formatters as git hooks with built-in parallelism, file locking (no race conditions), and staged-file-only operation (no separate lint-staged needed). Config is in Pkl — Apple's typed configuration language.

Mental Model

Every hk setup is three steps: detect what the project has → compose steps from tiers → wire the hooks in.

detect project type + tools
         ↓
compose hk.pkl (tiered steps)
         ↓
wire: mise.toml + .hk-hooks/ + prepare script

Setup Workflow

1. Detect

hk --version                    # get current version for amends URL
ls package.json go.mod Cargo.toml pyproject.toml flake.nix Makefile
cat mise.toml package.json      # existing tools, package manager, scripts

Identify:

  • Language(s) and framework
  • Package manager (pnpm/bun/npm/yarn for JS, cargo, go, pip, etc.)
  • Formatter already configured (prettier, biome, ruff, gofmt…)
  • Linter already configured (eslint, golangci-lint, ruff, clippy…)
  • Test runner (vitest, jest, go test, cargo test, pytest…)
  • Whether it's a team/shared repo (needs no-commit-to-branch)

2. Choose steps (tiered)

Tier 1 — Universal (always add):

StepBuiltin
trailing-whitespaceBuiltins.trailing_whitespace
newlinesBuiltins.newlines
check-merge-conflictBuiltins.check_merge_conflict

Tier 2 — Common tools (add if relevant):

StepBuiltinWhen
typosBuiltins.typosAlways (fast spell check)
gitleakscustomAlways (secret detection)
rumdlBuiltins.rumdlIf *.md files exist

Tier 3 — Language-specific (see references/builtins-by-language.md):

Signal fileSteps to add
package.json + biome.json/biome.jsoncbiome (or ultracite), eslint
package.json (no biome)prettier, eslint
tsconfig.jsontypecheck (tsc/tsgo/astro check/svelte-check)
go.modgo_fmt, go_vet, golangci_lint, gomod_tidy
Cargo.tomlcargo_fmt, cargo_clippy
pyproject.toml/requirements.txtruff (format+lint), mypy
flake.nix/*.nixnix_fmt (nixfmt), deadnix
*.sh/*.zshshfmt, shellcheck

Tier 4 — Project-specific (detect from config files):

SignalStep
commitlint.config.* existscommit-msg hook with commitlint
.yamllint* existsyamllint
Team/shared repono-commit-to-branch (pre-commit), no-push-to-branch (pre-push)
Test runner detectedtest step(s) — vitest/jest/go test/cargo test/pytest

3. Wire the hooks

Four files to create/update:

1. mise.toml — add hk, pkl, tool binaries 2. hk.pkl — configuration 3. scripts/quiet-on-success.sh — noise suppressor (copy from assets/quiet-on-success.sh in this skill) 4. .hk-hooks/pre-commit — tracked hook wrapper

Then:

chmod +x scripts/quiet-on-success.sh .hk-hooks/*
git config --local core.hooksPath .hk-hooks

And add to package.json prepare script (JS projects):

"prepare": "[ -n \"$CI\" ] && exit 0 || command -v hk >/dev/null && (hk install 2>/dev/null || git config --local core.hooksPath .hk-hooks) || echo 'Note: hk not found, skipping git hooks. Install mise to enable.'"

For non-JS projects, set core.hooksPath manually or via a Makefile setup target.

4. Validate

hk check --all      # verify all steps pass on existing files
hk validate         # verify hk.pkl is valid Pkl

---

Preferred Patterns

hk.pkl global settings

Always use these at the top (after the amends/import lines):

exclude = List("node_modules", "dist", ".next", ".git")  // add project-specific dirs
display_skip_reasons = List()   // suppress skip noise
terminal_progress = false        // cleaner output

Always use these on the pre-commit hook:

["pre-commit"] {
    fix = true        // auto-fix and re-stage
    stash = "git"     // isolate staged changes
    steps { ... }
}

Binary file excludes

Always exclude binary/font files from trailing-whitespace, newlines, and typos:

local binary_excludes = List(
    "*.png", "*.jpg", "*.jpeg", "*.gif", "*.webp", "*.ico",
    "*.woff", "*.woff2", "*.ttf", "*.eot", "*.pdf", "*.zip"
)

["trailing-whitespace"] = (Builtins.trailing_whitespace) {
    exclude = binary_excludes
}

The quiet-on-success wrapper

Wrap noisy commands so output only appears on failure:

["typecheck"] {
    check = "scripts/quiet-on-success.sh pnpm exec tsc --noEmit"
}

Copy assets/quiet-on-success.sh from this skill directory into scripts/ in the target repo.

The .hk-hooks/pre-commit wrapper

This is the file git actually executes. It's tracked in git (unlike .git/hooks/):

#!/bin/sh
# hk pre-commit hook — silent on success, minimal on failure
if [ -n "$CI" ]; then
  exec hk run pre-commit "$@"
fi
output=$(hk run pre-commit "$@" 2>&1)
code=$?
[ $code -ne 0 ] && printf '%s\n' "$output"
exit $code

For other hooks (commit-msg, pre-push), use simpler wrappers:

#!/bin/sh
exec hk run commit-msg "$@"
#!/bin/sh
exec hk run pre-push "$@"

---

Pkl Syntax Reference

Required first lines

amends "package://github.com/jdx/hk/releases/download/v1.36.0/hk@1.36.0#/Config.pkl"
import "package://github.com/jdx/hk/releases/download/v1.36.0/hk@1.36.0#/Builtins.pkl"

Always match the version in `amends` and `import` to the installed hk version (hk --version).

Builtin step (use as-is)

["trailing-whitespace"] = Builtins.trailing_whitespace

Builtin step (with overrides)

["trailing-whitespace"] = (Builtins.trailing_whitespace) {
    exclude = List("*.png", "*.jpg")
    batch = true
}

Custom step

["typecheck"] {
    glob = List("*.ts", "*.tsx")       // optional: only run when these files staged
    check = "scripts/quiet-on-success.sh pnpm exec tsc --noEmit"
    // fix = "command to auto-fix"     // optional
}

Template variables

VariableValue
{{files}}Space-separated list of staged files matching the step's glob
{{commit_msg_file}}Path to commit message file (commit-msg hook only)
{{workspace}}Directory containing workspace_indicator file
{{workspace_files}}Files relative to workspace directory

Multi-line inline script

["no-commit-to-branch"] {
    check = """
      branch=$(git rev-parse --abbrev-ref HEAD)
      if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
        echo "Direct commits to '$branch' are not allowed."
        exit 1
      fi
      """
}

Local variable (share steps across hooks)

local fast_steps = new Mapping<String, Step> {
    ["trailing-whitespace"] = Builtins.trailing_whitespace
    ["shfmt"] = (Builtins.shfmt) { batch = true }
}

hooks {
    ["pre-commit"] { fix = true; stash = "git"; steps = fast_steps }
    ["check"] { steps = fast_steps }
    ["fix"] { fix = true; stash = "git"; steps = fast_steps }
}

Sequential ordering with Groups

Steps within a group run in parallel; groups run sequentially:

steps {
    ["format"] = new Group {
        steps = new Mapping<String, Step> {
            ["prettier"] { ... }
            ["eslint"] { ... }
        }
    }
    ["validate"] = new Group {   // runs after format completes
        steps = new Mapping<String, Step> {
            ["typecheck"] { ... }
            ["test"] { ... }
        }
    }
}

Or use depends for fine-grained ordering:

["eslint"] {
    depends = List("prettier")   // waits for prettier to finish
    ...
}

---

mise.toml Additions

[tools]
hk = "latest"
pkl = "latest"        # required for hk.pkl parsing

# Add as needed based on detected steps:
typos = "latest"      # Tier 2: spell check
gitleaks = "latest"   # Tier 2: secret detection
rumdl = "latest"      # Tier 2: markdown lint (if .md files present)
yamllint = "latest"   # Tier 4: YAML lint (if .yamllint* present)

---

Maintenance

Add a new step

Insert into hk.pkl under the appropriate section. Check hk builtins for available built-ins, or write a custom step.

Update hk version

hk --version   # check current

Bump both URLs in hk.pkl:

amends "package://github.com/jdx/hk/releases/download/v1.37.0/hk@1.37.0#/Config.pkl"
import "package://github.com/jdx/hk/releases/download/v1.37.0/hk@1.37.0#/Builtins.pkl"

Bypass hooks temporarily

HK=0 git commit -m "wip"             # skip all hk hooks
HK_SKIP_STEPS=vitest git commit      # skip specific step

Debug a failing step

hk check -v                          # verbose output
hk check -v --step typecheck         # single step only
hk run pre-commit -v                 # simulate hook run

Local developer overrides

Create hk.local.pkl (gitignored) to override settings locally:

amends "./hk.pkl"
hooks {
    ["pre-commit"] {
        steps {
            ["vitest"] {
                check = "scripts/quiet-on-success.sh pnpm exec vitest run --testPathPattern=fast"
            }
        }
    }
}

---

Gotchas

IssueFix
pkl: command not foundAdd pkl = "latest" to mise.toml, run mise install
amends version mismatchMatch amends/import URL version to hk --version output
Builtins snake_case vs step names kebab-caseBuiltins.trailing_whitespace["trailing-whitespace"]
Hook runs but matches nothingCheck glob patterns; use hk check -v to see file matching
Binary files fail spell checkAdd binary excludes to typos/trailing-whitespace/newlines steps
Git worktrees: hk install failsAutomatic since v1.35.0; if using older version use .hk-hooks/ + core.hooksPath
Fix auto-stages wrong filesUse explicit stage glob on the step, or ensure step glob covers fixed files
Noisy output on successWrap commands in scripts/quiet-on-success.sh
Hook runs in CI unnecessarilyAdd [ -n "$CI" ] && exit 0 to prepare script
hk.local.pkl uses amends not being honouredFirst line must be amends "./hk.pkl"

---

References

  • references/builtins-by-language.md — step selection by ecosystem
  • references/complete-examples.md — full hk.pkl configs for different stacks
  • assets/quiet-on-success.sh — copy into scripts/ in target repo
  • hk docs — official documentation
  • hk builtins — list all 90+ available built-in linters

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.