npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mvframe

v1.0.11

Published

**English** | [简体中文](README.cn.md)

Readme

MVFrame

English | 简体中文

A Vue 3 + Vite oriented admin-shell toolkit: Frame layout, common business components, global utilities & directives, Pinia wiring with tabs/router, composable modules, and SCSS utilities & tokens. Priorities favor SaaS-style admin apps over a fully pluggable, zero-opinion utility library.


Stack & dependencies

| Kind | Notes | |------|------| | Runtime | vue ^3.3, vue-router ^4.6, pinia ^3 | | Demo / dev | element-plus (demo forms, etc.), vite ^6, sass-embedded | | Build | Library output is ESM; vue / pinia / vue-router are externals and must be supplied by the host app |

package.json exports include:

  • "."dist/index.js (main plugin; default export is the install function)
  • "./composition"dist/composition.js (e.g. import { useMap } from 'mvframe/composition')
  • "./store", "./directive", "./util" → matching chunks under dist
  • "./style"dist/css/style.css (full toolkit CSS from src/style/index.scss entry)
  • "./style/cpt"dist/css/cpt.css (component-extracted CSS; usually import 'mvframe/style' is enough)

Repository layout

src/ — library source

| Path | Role | |------|------| | src/index.js | Install entry: registers config → global components (cpt) → utildirectivestorerouter | | src/config/ | Merges defaults with app options → globalThis.$config (chip/base.js: name, copyright, version, etc.) | | src/cpt/index.js | Auto-registers every component/*/index.vue via import.meta.glob; component name equals the folder name (PascalCase, e.g. BtnGroup) | | src/component/ | Implementations; root class Mvc + name (see .cursor/rules/component-hierarchy.mdc) | | src/util/index.js | Global helpers on app.config.globalProperties & globalThis ($getLang, $fa, $copy, $deepClone, …) | | src/directive/index.js | Directives: v-copy (optional .dblclick), v-focus | | src/store/ | createPinia + built-in init / tab / rmenu; optional storeChips; provide("store", store) | | src/router/ | createWebHistory router; optional guard; built-in guardThis (meta.admin, afterEach + tabs, document.title) | | src/composition/ | Import on demand; exports lang, dom, data, media, … (Vite alias @cps → this folder) | | src/style/ | index.scss aggregates chip/*.scss (tokens, spacing, typography, layout, overrides) |

Globally registered components (folder name = registration name):

BtnGroup, Form, Frame, Icon, Input, Page, Select, SelectV2, Table, Tabs, Textarea

chip/ subfolders hold internal pieces (e.g. Frame/chip/Menu.vue); they are not registered as root components.

demo/ — local preview app

With NODE_ENV=development, Vite root is ./demo (see vite.config.js) to exercise Frame, routing, and components.

| File | Role | |------|------| | demo/index.html | HTML shell | | demo/main.js | Boot: ElementPlus + ../src/index.js + ../src/style/index.scss + routes | | demo/App.vue | Frame layout, menu: { iconClass: 'imicon', routes }, slots logo / logomini | | demo/routes.js | Sample routes: /Overview/Home, /aA/Home; nested children for the sidebar | | demo/views/Overview/Home.vue | Page + Tabs switching FormPanel / IconPanel | | demo/views/Overview/Home/FormPanel.vue | Form demo | | demo/views/Overview/Home/IconPanel.vue, iconfontAntNames.js | Icon demo & Ant icon name list | | demo/auto-imports.d.ts | Types from unplugin-auto-import (Vue / vue-router) |

Local dev:

yarn install
yarn dev

Dev server port 8088 (see vite.config.js).

Path aliases

| Alias | Points to | |------|-----------| | @ | src/ | | @cps | src/composition/ | | @scss | assets/scss (if present) |

Demo routes use paths like import("/views/Overview/Home.vue") resolved from the demo root.


Using in a host application

1. Install peer-style deps

Align versions of vue, vue-router, pinia. For Form / Table tied to Element Plus, add element-plus and app.use(ElementPlus).

2. Register MVFrame

import { createApp } from "vue";
import mvframe from "mvframe";
// Styles: use package path when depending on source / monorepo; published `dist`-only—see “Styles”
import "mvframe/src/style/index.scss";

const app = createApp(App);

app.use(mvframe, {
  vueRouter: {
    routes: yourRoutes,
    // optional: custom beforeEach, etc.
    // guard: (router) => { /* ... */ },
    // useAdmin: true,
    // adminPermission: () => true,
    // noaccess: (next) => next(false),
  },
  pinia: {
    useTab: true, // multi-tab + localStorage restore for `tabs` / `ctab`
    // storeChips: import.meta.glob("./pinia/chip/*.js", { eager: true }),
  },
  config: {
    // merged with src/config/chip/base.js → globalThis.$config
    iconfont: {
      url: "//at.alicdn.com/t/c/your_font.js",
      prefix: "ant",
    },
  },
});

Frame injects a <script> for icon fonts from globalThis.$config.iconfont.url on mount (implementation removes url afterward to avoid duplicate injection).

3. Globals at a glance

  • globalThis.$config — merged app config
  • globalThis.$router — router instance assigned by this library after install
  • inject("store") — store factory (store.tab(), store.rmenu(), custom chips)
  • Global components — use Frame, Page, Table, … without local registration
  • Directivesv-copy, v-focus
  • Compositionimport { ... } from "mvframe/composition" or your @cps alias

Full helper list: .cursor/rules/util.mdc and src/util/index.js.

4. Styles

  • Utility classes & tokens: .cursor/rules/style-system.mdc (--color-*, spacing, typography, layout).
  • vite.config.js additionalData injects src/style/chip/mixin.scss; mirror this in apps that compile the same SCSS tree.
  • Published packages can use import 'mvframe/style' (dist/css/style.css). For SCSS overrides, still link src/style/index.scss from Git/monorepo when needed.

Building the library

yarn build

Production uses library mode with entry src/index.js and obfuscation-related plugins (see vite.config.js). NODE_ENV=development points Vite at the demo app; to verify a real build locally, run production vite build (or your script that sets production env).


Design notes

  • Layout, guards, tabs, and menu behavior are opinionated; heavy customization may mean forking src/router, src/store/tab.js, or wrapping from the app.
  • CSS naming & units: root Mvc*, children camelCase; prefer rem for sizes other than 1px/2px (16px root)—see style-system.mdc.
  • Use globalThis or store / pinia exports outside setup (e.g. guards), as in src/router/chip/guard.js.

CLI: project skeleton

From an empty folder or existing Vite root, generates src/views, src/component, src/api, src/assets/img, src/assets/style, src/router, src/pinia/chip, src/config, plus starter main.js / App.vue with app.use(mvframe, …) (routes, Pinia storeChips, config). Adds index.html and vite.config.js only if missing (use --force to overwrite). Merges dependencies / devDependencies into package.json (existing versions win for shared keys); use --no-package-json to skip. Then run yarn install.

cd /path/to/your-app
node /path/to/mvframe/scripts/scaffold-app.js
node /path/to/mvframe/scripts/scaffold-app.js --force

# Skip package.json (only scaffold sources + Vite config):
node /path/to/mvframe/scripts/scaffold-app.js --no-package-json

yarn exec mvframe-init-app
# or: npx mvframe-init-app

See MVFRAME-SCAFFOLD.md in the target project. Set MVFRAME_SCAFFOLD_TARGET to point at the project root.


Cursor Skill (app scaffold)

This repo ships .cursor/skills/mvframe-app-init. Copy it into your app’s .cursor/skills so Cursor can pick up MVFrame integration conventions.

From your app root, run either:

# Full checkout / monorepo path to mvframe
node /path/to/mvframe/scripts/install-cursor-skill.js
node /path/to/mvframe/scripts/install-cursor-skill.js /path/to/your-app

# After installing the npm package (the tarball must include `scripts/` and `.cursor/skills`—see `package.json` `files`)
cd /path/to/your-app
yarn exec mvframe-install-cursor-skill
# or: npx mvframe-install-cursor-skill

Default target is ./.cursor/skills/mvframe-app-init under the current working directory. Override with MVFRAME_CURSOR_SKILL_OUT=/path/to/your-app.


License

ISC (see package.json).