@osmeridian/lint-typecheck-format-test

Shared lint, format, typecheck defaults, and vitest factory for Omniswift Vue/Nuxt apps
Install
npm install @osmeridian/lint-typecheck-format-test
Latest Version:1.1.2
Vue:3
License:Proprietary
Last Updated:Aug 17, 2026
Links: npm
Maintainer: omniswift

@osmeridian/lint-typecheck-format-test

Shared lint, format, typecheck defaults, and Vitest factory for Omniswift Vue/Nuxt apps.

Rule changes belong in this package only. Consuming apps keep thin re-exports and allowlisted overlays — do not copy or edit shared rule tables locally.

Copy-paste stubs: examples/nuxt-consumer/.

Engines: Node >=22.18.0 <25, pnpm >=10.

Install

pnpm add -D @osmeridian/lint-typecheck-format-test oxc-nuxt eslint@10.8.1 oxlint-tsgolint@7.0.2001

Or pin an exact version:

{
  "devDependencies": {
    "@osmeridian/lint-typecheck-format-test": "1.1.2",
    "eslint": "10.8.1",
    "oxc-nuxt": "^0.1.5",
    "oxlint-tsgolint": "7.0.2001"
  }
}
Peer Required? Role
eslint Yes Direct install so the editor ESLint extension can resolve the binary and show diagnostics
oxlint-tsgolint Yes Direct install so Oxlint --type-aware / Nuxt builds can resolve tsgolint from the app
oxc-nuxt Yes (Nuxt) Registers Nuxt auto-import globals for Oxlint via .nuxt/oxlint.mjs / withNuxt
vitest Optional Needed if you use /vitest
@vitejs/plugin-vue Optional Used by the Vitest factory
happy-dom Optional Vitest environment: "happy-dom"

Install the exact eslint and oxlint-tsgolint versions listed here — not ^ / >= / “whatever is current.”

ltft runs the copies bundled in this package. The editor and Oxlint type-aware lookup use the copies in the app. Those two paths must be the same version, or IDE squiggles and CI will disagree. oxlint and oxlint-tsgolint are also paired; a newer tsgolint with an older oxlint (or the reverse) breaks --type-aware. Shared rule tables are tested against these pins — bump them in this package, then bump the app to match.

Oxlint, Prettier, and related plugins still ship with this package for ltft lint / ltft format.

Apply in a Nuxt app

1. Register oxc-nuxt

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ["oxc-nuxt" /* ... */],
});

This package does not bundle or register that module.

2. Prepare Nuxt

nuxt prepare

This generates .nuxt/oxlint.mjs (withNuxt) so Oxlint knows Nuxt auto-import globals.

3. Add thin config files

ESLint — re-export the shared flat config:

// eslint.config.js
export { default } from "@osmeridian/lint-typecheck-format-test/eslint";

Oxlint — wrap shared rules with withNuxt:

// oxlint.config.ts
import { withNuxt } from "./.nuxt/oxlint.mjs";
import { baseOxlint } from "@osmeridian/lint-typecheck-format-test/oxlint";

export default withNuxt({
  ...baseOxlint,
  overrides: [...(baseOxlint.overrides ?? []), /* app-only overrides */],
});

Prettier — spread shared options; set app Tailwind paths:

// .prettierrc.mjs
import base from "@osmeridian/lint-typecheck-format-test/prettier";

export default {
  ...base,
  tailwindStylesheet: "./app/assets/styles/tailwind.css",
  tailwindFunctions: ["cn", "clsx"],
};

The Tailwind plugin path is resolved inside this package — no consumer createRequire needed.

Typecheck defaults (optional):

import { nuxtTypescriptDefaults } from "@osmeridian/lint-typecheck-format-test/typescript/nuxt";

export default defineNuxtConfig({
  typescript: {
    tsConfig: {
      ...nuxtTypescriptDefaults,
      // app paths / excludes
    },
  },
});

Vitest (optional):

import { fileURLToPath } from "node:url";
import { createVitestConfig } from "@osmeridian/lint-typecheck-format-test/vitest";

const rootDir = fileURLToPath(new URL(".", import.meta.url));

export default createVitestConfig({
  rootDir,
  aliases: [
    /* app-specific fixture aliases */
  ],
});

4. Add scripts

{
  "scripts": {
    "lint": "ltft lint",
    "lint:fix": "ltft lint:fix",
    "format": "ltft format",
    "format:fix": "ltft format:fix",
    "typecheck": "nuxt typecheck",
    "test": "vitest run"
  }
}

CLI

ltft lint           # oxlint then eslint; fails on warnings
ltft lint:fix      # same with --fix
ltft format         # prettier --check
ltft format:fix    # prettier --write
ltft format:check   # alias for format
ltft help

typecheck and test stay as app scripts (nuxt typecheck, vitest run) — they are not part of ltft.

This package does not ship lint-staged or husky. Wire pre-commit hooks in the app if you want them.

How ltft lint works

ltft lint always runs both tools, in order. Either step exits non-zero on failure; warnings are treated as failures.

Step Tool Scope Failure policy
1 Oxlint Entire project (.) --type-aware --deny-warnings
2 ESLint app/**/*.vue, **/utils/**/*.{ts,js,mts,cts,mjs,cjs}, and hexagonal feature/component TS layers --max-warnings=0

What Oxlint and ESLint do

They are complementary, not alternatives.

Tool Scope Role
Oxlint Whole project Fast primary linter: categories, plugins, and type-aware rules (oxlint-tsgolint). Nuxt globals come from oxc-nuxt / withNuxt.
ESLint Vue SFCs + utils paths + hexagonal layers Gaps Oxlint does not cover well: custom Vue attribute order, unused vars across script + template in .vue, utils -utils filename convention, and hexagonal no-restricted-imports.

Rules and config reference

Oxlint (baseOxlint)

Source: src/oxlint/base.js.

Categories

Category Level
correctness error
suspicious error
perf warn
style warn
pedantic off
restriction off

Enabling a category turns on many plugin defaults beyond the explicit rules table below. Those explicit entries are overrides and additions.

Options: denyWarnings: true, typeAware: true.

Plugins: eslint, import, node, oxc, promise, typescript, unicorn, vue (plus JSDoc via a path override).

Explicit top-level rules

Rule Config
eslint/curly off
eslint/eqeqeq error, always, { null: "ignore" }
eslint/func-style error, "expression"
eslint/no-alert error
eslint/no-console warn
eslint/no-debugger error
eslint/no-duplicate-imports error
eslint/no-magic-numbers warn
eslint/no-var error
eslint/no-ternary off
eslint/one-var off
eslint/capitalized-comments off
eslint/prefer-const error
eslint/sort-keys off
import/first error
import/group-exports off
import/no-named-export warn
import/no-cycle warn
import/no-duplicates error
import/no-self-import error
import/no-unassigned-import off
import/consistent-type-specifier-style off
promise/always-return off
promise/no-callback-in-promise error
promise/no-return-wrap error
promise/prefer-await-to-then off
typescript/await-thenable error
typescript/consistent-type-imports error; separate-type-imports, prefer type-imports
typescript/no-explicit-any error
typescript/no-floating-promises error
typescript/no-misused-promises error
typescript/no-unnecessary-type-assertion error
typescript/prefer-nullish-coalescing warn
typescript/prefer-optional-chain warn
unicorn/no-array-for-each off
unicorn/no-null off
unicorn/prefer-node-protocol error
unicorn/prefer-string-slice error
vue/no-export-in-script-setup error
vue/return-in-computed-property error
vue/valid-define-emits error
vue/valid-define-props error

Path overrides

Files Effect
**/*.{spec,test}.{ts,js}, **/__tests__/**, tests/**/*.ts Relaxes many eslint/import/typescript/unicorn/vue rules for tests
app/core/ports/**/*.ts import/no-named-export off
app/stores/**/*.ts eslint/max-params off
app/features/**/application/**/*.ts, app/core/application/**/*.ts max-statements / prefer-nullish-coalescing / consistent-function-scoping off
app/types/**/*.d.ts init-declarations, no-var, vars-on-top, no-named-export, require-module-specifiers off
nuxt.config.ts, server/**/*.ts, vitest.config.ts Node env; import/no-nodejs-modules off
app/utils/magic-numbers-utils.ts eslint/no-magic-numbers off
app/utils/promise-helpers-utils.ts promise/avoid-new off
Package / local eslint-rules JS no-continue, no-magic-numbers off
app/composables/**/*.{ts,js}, app/components/**/*.vue, app/pages/**/*.vue JSDoc required (require-jsdoc, require-description)

ESLint

Source: src/eslint/index.js.

Built on eslint-plugin-vue flat/base plus a local plugin.

Utils files — **/utils/**/*.{ts,js,mts,cts,mjs,cjs} (ignores *.{spec,test}.* and __tests__):

Rule Severity
local/utils-filename-suffix error

Filenames under a utils/ directory must end with -utils (e.g. date-utils.ts). Names of 2 characters or fewer (e.g. cn.ts) are exempt.

Vue SFCs — app/**/*.vue:

Rule Severity / notes
vue/attributes-order off (conflicts with local autofix)
local/static-before-dynamic-attrs error; autofixable
@typescript-eslint/no-unused-vars warn; ignore ^_ for args/vars/caught/destructured
vue/no-unused-vars warn; ignorePattern: "^_"

Hexagonal import bans — no-restricted-imports (source: src/eslint/hexagonal.js):

Files Must not import
app/features/*/application/**/*.ts useCustomFetch, endpoint-utils, infrastructure, adapters, composition
app/features/*/ui/**/*.vue useCustomFetch, endpoint-utils, infrastructure, adapters, application
app/features/*/composition/**/*.ts useCustomFetch, endpoint-utils, infrastructure
app/features/*/adapters/**/*.ts useCustomFetch, application, UI, composition
app/components/**/*.{vue,ts} useCustomFetch, endpoint-utils
app/features/*/domain/**/*.ts useCustomFetch, endpoint-utils, infrastructure, adapters, application, composition, UI, vue, nuxt/app, #app, @tanstack/vue-query

Optional named export: @osmeridian/lint-typecheck-format-test/eslint/hexagonal (already included in the default /eslint config).

Attribute order (local/static-before-dynamic-attrs):

  1. Definition (is)
  2. List rendering (v-for)
  3. Conditionals (v-if / v-else-if / v-else / v-show / v-cloak)
  4. Render modifiers (v-pre / v-once)
  5. Global (id)
  6. Unique / slot (key, ref, slot)
  7. Two-way binding (v-model)
  8. Other directives
  9. Static attributes (class, role, …)
  10. Dynamic attributes (:prop, v-bind)
  11. Boolean shorthand
  12. Events (@click, …)
  13. Content (v-text / v-html)

Prettier

Source: src/prettier/index.js.

Option Value
useTabs true
tabWidth 2
semi true
singleQuote false
printWidth 100
trailingComma "all"
plugins prettier-plugin-tailwindcss (resolved from this package)

ltft format always applies:

  1. This package’s prettierignore (.nuxt, .output, node_modules, dist, lockfiles, package.json, …)
  2. The project’s .gitignore when present
  3. The project’s .prettierignore when present

Keep app-specific excludes in the project .prettierignore only.

TypeScript defaults

nuxtTypescriptDefaults sets:

{ vueCompilerOptions: { checkUnknownProps: true } }

Oxlint --type-aware is separate from nuxt typecheck — use both.

Vitest factory defaults

createVitestConfig({ rootDir, ... }) defaults:

Setting Default
Environment happy-dom
Includes `app/features
Setup tests/setup/vitest-setup.ts
Aliases ~ → ./app, @tests → ./tests
Defines import.meta.client = true, import.meta.server = false

Pass aliases, include, setupFiles, or overrides for app-specific needs.

Overlay allowlist

Allowed in consumers:

File Purpose
oxlint.config.ts app overrides Path-specific rule exceptions
.prettierrc.mjs tailwindStylesheet / tailwindFunctions
nuxt.config.ts Merge typecheck defaults + app tsConfig
vitest.config.ts Root, includes, aliases, setup files

Not allowed: copying or editing shared rule tables from this package into the app.

Requesting rule changes

Open a PR against osmeridian/lint-typecheck-format-test, bump the consumer dependency pin after the release.

Package exports

Export Provides
@osmeridian/lint-typecheck-format-test/eslint Shared ESLint flat config + custom Vue attr rule + utils -utils filename rule + hexagonal import bans
@osmeridian/lint-typecheck-format-test/eslint/hexagonal Hexagonal no-restricted-imports overlay (included in /eslint)
@osmeridian/lint-typecheck-format-test/oxlint baseOxlint object
@osmeridian/lint-typecheck-format-test/prettier Base Prettier options
@osmeridian/lint-typecheck-format-test/vitest createVitestConfig
@osmeridian/lint-typecheck-format-test/typescript/nuxt nuxtTypescriptDefaults

Exports include TypeScript types — consumers do not need local declare module shims.

Example stubs

See examples/nuxt-consumer/ for ESLint, Oxlint, Prettier, Vitest, and package.json script stubs.

Related Packages

@lupinum/website-config

Shared Vite+ and template ESLint configuration for Lupinum Nuxt websites.

190 0
@novicell/eslint-config-nuxt

A Eslint config for Nuxt projects with TypeScript

2,110
@maprox/lint-config

Shared ESLint flat configs (base, vue, astro, node, opt-in tailwind) + oxlint sk...

820
fg-devkit

Shared configs, scripts, and DX tooling for Vue / TypeScript frontend repos

14,112
vue-eslint-standard

quickly start eslint in vue

3,269 1

Version History

Version Released License
1.1.2 Proprietary
1.1.1 Proprietary
1.1.0 Proprietary
1.0.7 Proprietary
1.0.6 Proprietary