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

@lilaquadrat/design-core

v0.2.0

Published

framework layer shared by every lilaquadrat STUDIO design: app bootstrap, router, stores, plugins and build tooling

Readme

lilaquadrat STUDIO

@lilaquadrat/design-core

The framework half of a STUDIO design.

A design repository used to carry two things at once: the design (modules, partials, less, gallery fixtures) and the machinery that makes it an app (bootstrap, router, stores, plugins, models, build tooling). Only the first half differs between projects. This package is the second half, so a design update no longer means porting framework changes by hand into every project.

The design stays in the project. Everything else lives here.

What is in here

| path | what | | --- | --- | | main, client-entry, server-entry | app bootstrap for browser, hydration and SSR | | routes, mixins/getRoutes, mixins/createRouter, mixins/hooks | routing, the auth and signup gate, scroll behaviour | | mixins/loadComponents | module and partial registration, editor module list | | stores/* | main, user, content, editor, files, cart, calls | | plugins/* | auth, currency, events, filters, inview, replacer, resize, signupFlow, traceable, translations, youtube | | libs/* | Models.class, ActionNotice | | functions/* | payment provider factory, shopify and stripe providers, dom helpers | | models/* | Address and Contact declarations | | mixins/* | date, formatSize, getAnchor, hasSlotContent, replaceVariables, createCookieString, logger | | views/* | content, editor, login, signup-account, download | | partials/* | client-only, main-components, error, qrcode, action, mediadetection | | translations/de | framework wording only - validation, lists, files, signup, order | | vite, eslint, stylelint, cypress | build and test tooling |

What is NOT in here, on purpose

Modules, partials, assets/less (variables, mixins, fonts, theme), the gallery (preview.view.vue, viewData/*, preview-controls, preview-colors, previewTheme, paletteDerive), the contrast audit, the module registries (modules.browser.ts, partials.browser.ts and the mail pair), config.ts, staticData.ts and every module-shape interface.

Those are the design. They change per project, and a package version has no business deciding what they look like.

Source, not a build

The package exports .ts and .vue source. Two of the views carry scoped less that uses the project's own variables and mixins, injected by vite's globalVars. A prebuilt stylesheet would bake this repo's palette into every project, so the consumer compiles the source instead:

optimizeDeps: { exclude: ['@lilaquadrat/studio', '@lilaquadrat/design-core'] }

createViteConfig already sets that.

Using it in a design

vite

// vite.config.ts
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import { createViteConfig } from '@lilaquadrat/design-core/vite';
import config from './config.ts';

export default defineConfig(createViteConfig({
  config,
  root   : fileURLToPath(new URL('.', import.meta.url)),
  lessDir: './src/assets/less',
}));

entry

The project owns App.vue (global styles, editor wiring) and the module registries, so it hands them to the package:

// src/client-entry.ts
import { createClientEntry } from '@lilaquadrat/design-core/client-entry';
import { dynamicRoutes, editorRoutes, createPreviewRoutes } from '@lilaquadrat/design-core/routes';
import App from './App.vue';
import PreviewView from '@/views/preview.view.vue';
import TestView from '@/views/test.view.vue';
import modules from './modules.browser';
import partials from './partials.browser';
import modulesMail from './modules.mail';
import partialsMail from './partials.mail';

createClientEntry({
  components: {
    root        : App,
    modules     : modules.modules,
    partials,
    modulesMail : modulesMail.modules,
    partialsMail,
  },
  routes: {
    dynamicRoutes,
    editorRoutes,
    previewRoutes: createPreviewRoutes(PreviewView, TestView),
  },
});

render from @lilaquadrat/design-core/server-entry takes the same components object through its options argument.

translations

The package ships the strings it renders itself. Module wording belongs to the design and is merged on top:

import { addMessages } from '@lilaquadrat/design-core/plugins/translations';
import de from '@/translations/de';

addMessages('de', de);

eslint, stylelint, cypress

// eslint.config.js
export { default } from '@lilaquadrat/design-core/eslint';
// cypress.config.ts
import { createCypressConfig } from '@lilaquadrat/design-core/cypress';

export default createCypressConfig();

cy:parallel bin-packs specs by measured runtime. A project with its own spec set overrides the table in cypress/durations.json.

SSR preflight

tooling/ssr-test renders a whole design through the real ssr build and fails if anything in it throws, warns or comes back empty. It is the gate before publishing.

It exists because the production renderer is forgiving in the worst way: RenderClass.renderSingle collects renders with Promise.allSettled and only console.errors a rejected one, so a page that blows up during SSR is published as an empty shell and nobody notices.

Offline by construction - the two build artifacts are the only input, nothing talks to an api:

dist/server      the published ssr build   (yarn build-ssr)
dist/ssr-test    the design's fixtures     (yarn build:ssr-fixtures)
// src/ssr-test.fixtures.ts - built with: vite build --ssr --mode ssr-test
import type { Content } from '@lilaquadrat/interfaces';
import modulesBrowser from './modules.browser';
import text from './views/viewData/text';

export const viewData: Record<string, Content> = { text };
export const modules = modulesBrowser.modules.map((single) => ({
  name    : single.name,
  variants: (single.variants ?? []).map((variant) => ({ key: variant.key })),
}));
// test/ssr.test.mjs - run with: node --test test/*.test.mjs
import { runSsrSuite } from '@lilaquadrat/design-core/ssr-test';

const fixtures = await import('../dist/ssr-test/ssr-test.fixtures.js');

await runSsrSuite({ fixtures });

Three passes:

| pass | what it renders | | --- | --- | | viewData | every gallery fixture as its own site, at its own url | | empty modules | every registered module with nothing but a type and a uuid, then once per registered variant | | empty mail modules | the same for the mail registry, rendered at the mail url |

Every render is asserted to resolve, to log no console.error and no [Vue warn], to produce the content module, to return parseable initialState, and to fill in the html template's placeholders. The context it passes is the one RenderClass.createGenericContext builds, so what the suite exercises is the contract the renderer actually uses.

Options:

  • allowedConsole - regexes for output the project expects offline (a module that needs a structure declaration or a payment provider from the backend). Reported as a diagnostic instead of failing.
  • markers - root class overrides for modules whose class does not follow from their type.
  • variants: false - render each module once instead of once per variant.
  • paths - where the build output lives, if not the defaults above.

A module that renders nothing for empty data is fine and is reported, not failed. A module that throws on empty data is the thing this suite is for.

Migrating an existing design

Keep the old import paths working with a one line shim per file, then delete the shims per project whenever convenient:

// src/stores/main.store.ts
export * from '@lilaquadrat/design-core/stores/main.store';
export { default } from '@lilaquadrat/design-core/stores/main.store';

The subpaths mirror the layout a design already had, so the shim is always the same two lines and no component import has to change.

The one seam that matters

The package never imports a design component. main-components.partial.vue and error.partial.vue render lila-content-module by its global component name, resolved at runtime from the registry the project passed in. That keeps the dependency one-directional: design depends on core, core never on design.

Known state

yarn type-check reports the errors this code already had inside the design repo - Models.class, main.store, action.partial, the shopify provider and Contact.model. They were not introduced by the extraction and are unchanged from their origin. One extra error in user.store is an artifact of this repository's own dev tree carrying two copies of @lilaquadrat/interfaces; a consuming project with a single hoisted copy does not see it.