@makashif/brand

A branded developer signature for every surface — an interactive DevTools console card, a live on-page brand card, and an ANSI terminal banner. One drop-in for Next.js, Astro, Nuxt, SvelteKit, Node, Express or plain HTML.
Install
npm install @makashif/brand
Latest Version:1.0.15
Vue:3
License:MIT
Last Updated:Aug 28, 2026
Links: GitHub  ·  npm
Maintainer: makashif

@makashif/brand

One identity, every surface. An interactive DevTools console signature, a live on-page brand card, and an ANSI terminal banner — from a single config.

npm i @makashif/brand

That is the whole setup. A postinstall hook detects your framework and wires itself in — it prints exactly what it did, and never touches anything twice.

Stack What gets wired How
Next.js instrumentation-client.ts + instrumentation.ts new files
Nuxt plugins/brand.client.ts new file
SvelteKit src/hooks.client.ts new file
Astro astro.config.mjs → integrations: [brand()] injected, then verified
Vite / React / Vue SPA one import at the top of your app entry prepended
Express / Node / HTML prints the one line to add nothing written

Not automatic enough, or you skipped install scripts? Same thing, on demand:

npx @makashif/brand init

How the automatic wiring stays safe

Writing to someone's project during an install deserves real caution, so this is deliberately narrow:

  • It only ever creates a new file, prepends one import, or edits a config whose result still parses. Config edits are verified with node --check and rolled back if they don't. A TypeScript config is never machine-edited — node --check can't validate TS, and an unverifiable rewrite of a build config isn't worth the risk, so you get the two lines to paste instead.
  • It never overwrites. An existing file is reported and left alone; running it again is a no-op.
  • It never fails your install. Every path exits 0 — a cosmetic feature must not break npm install.
  • It skips CI, so no surprise diffs in a pipeline.
  • It skips transitive installs. If another package depends on this one, your project is not touched.
  • It tells you how to undo it on every run.

Opt out any of three ways:

MAKASHIF_BRAND_SKIP=1 npm i @makashif/brand
npm i @makashif/brand --ignore-scripts
{ "makashifBrand": { "autowire": false } }

One honest limitation: postinstall runs in your terminal, not a browser. It can't print to a visitor's console directly — what it does is write the file that makes your app load the branding on every page. And --ignore-scripts, which many teams set globally, skips it entirely; npx @makashif/brand init is the fallback.

Or wire it by hand

One side-effect import, anywhere in your entry:

import '@makashif/brand/auto';

Or drive it explicitly:

import { brand } from '@makashif/brand';

brand();

In a browser that prints the console signature; in Node it prints the terminal banner. Same call — the package routes itself through the node export condition.


What you get

Surface Where What it does
Console signature Browser DevTools Gradient badges, an SVG monogram, collapsible sections, a sortable capability table, live GPU/paint telemetry, and a makashif.* namespace you can drive by hand
Brand card On the page A self-contained Shadow DOM card with a live FPS meter, expandable disciplines, copy-to-clipboard and a hire button
Terminal banner Node, Express, CI A truecolor box that sizes itself to its content, honours NO_COLOR, and ships Express/Fastify/Koa middleware

Automatic, per stack

Each of these is the whole integration — no component to render, no layout to edit. npx @makashif/brand init sets it up for you.

Stack File / config Loaded by
Next.js instrumentation-client.ts → import '@makashif/brand/auto' Next, on every page before hydration
Nuxt plugins/brand.client.ts Nuxt auto-registers plugins/
SvelteKit src/hooks.client.ts → import '@makashif/brand/auto' SvelteKit, on every route
Astro integrations: [brand()] from /astro-integration injected into every page
Vite (any SPA) plugins: [brand()] from /vite injected into index.html
Express app.use(brandMiddleware()) your server entry
// astro.config.mjs
import brand from '@makashif/brand/astro-integration';
export default defineConfig({ integrations: [brand()] });
// vite.config.ts
import brand from '@makashif/brand/vite';
export default defineConfig({ plugins: [brand()] });

Explicit, per stack

When you want the card in a specific place, or control over where the signature prints.

Next.js / React
// The adapter carries its own 'use client' boundary — a Server Component can
// import it directly, no wrapper file needed.
import { ConsoleBrand, BrandCard } from '@makashif/brand/react';

export default function Layout({ children }) {
  return (
    <body>
      <ConsoleBrand />          {/* renders no DOM */}
      {children}
      <BrandCard variant="badge" scheme="auto" />
    </body>
  );
}

Add instrumentation.ts to brand your server boot too:

export async function register() {
  const { brand } = await import('@makashif/brand');
  brand();
}
Astro
---
import Brand from '@makashif/brand/astro';
---
<Brand variant="badge" scheme="auto" />
Nuxt / Vue
<script setup>
  import { ConsoleBrand, BrandCard } from '@makashif/brand/vue';
</script>

<template>
  <ConsoleBrand />
  <BrandCard variant="badge" />
</template>

Or install both globally:

// plugins/brand.client.ts
import BrandPlugin from '@makashif/brand/vue';
export default defineNuxtPlugin((nuxt) => nuxt.vueApp.use(BrandPlugin));
SvelteKit
<script>
  import { brandCard, consoleBrand } from '@makashif/brand/svelte';
  consoleBrand();
</script>

<div use:brandCard={{ variant: 'badge' }}></div>
Node / Express / Fastify / Koa
import express from 'express';
import { brandMiddleware } from '@makashif/brand/express';

const app = express();
app.use(brandMiddleware());   // banner on first request + X-Designed-By header
import { brand, brandBanner } from '@makashif/brand/node';

brand();                            // print it
const text = brandBanner({ color: false });   // or capture it for a logger
Angular, Solid, Qwik, Rails, Laravel, WordPress, plain HTML
<script type="module">import '@makashif/brand/element';</script>
<brand-card variant="badge"></brand-card>

Or with no build step and no install at all:

<div data-brand></div>
<script src="https://unpkg.com/@makashif/brand"></script>

Make it yours

Every field is optional and overridable — the defaults are just one identity.

brand({
  name: 'Your Name',
  tagline: 'Designer · Developer',
  monogram: 'Y',
  links: { portfolio: 'https://example.com', github: '…', email: 'you@example.com' },
  chips: ['Svelte', 'Rust', 'WebGPU'],
  capabilities: [{ discipline: 'Systems', focus: 'Rust · WASM', level: 'Expert' }],
  theme: { brand: '#f43f5e', info: '#f59e0b' },
  api: 'me',            // → window.me instead of window.makashif
});

The console namespace

Every member is a getter, so no parentheses are needed — and because DevTools shows accessors as click-to-invoke, merely expanding the object never fires a side effect.

Click to run

The banner (and makashif.help) logs a command object you can drive with the mouse:

makashif commands {visit: (…), code: (…), hire: (…), copy: (…), help: (…)}

Expand it and click any (…) — DevTools evaluates the accessor, which runs the command. No typing.

This is the only real click-to-execute mechanism a console has: styled %c text cannot carry a click handler, and no API exists to give it one. Accessor evaluation is the genuine article, and each entry delegates to the same getter on the namespace, so a click and a typed makashif.visit run one code path rather than two that can drift apart.

makashif.help      makashif.runtime    makashif.hire
makashif.whoami    makashif.banner     makashif.visit
makashif.stack     makashif.card       makashif.code
makashif.skills    makashif.config     makashif.copy

Options

Option Default Notes
name tagline craft domain shipped identity The header block
monogram 'M' One or two characters. 'M' gets the drawn wordmark
links portfolio/github/email Any extra key renders as another row
stack capabilities chips shipped content Arrays replace, they don't merge
theme violet/cyan palette Merges over the dark defaults
themeLight darkened palette Light-mode overrides; your theme hues carry over automatically
scheme 'auto' Console palette: follows prefers-color-scheme, or force 'dark'/'light'
version env auto-detected env falls back to NODE_ENV
logo groups telemetry true telemetry: 'only' skips stack + capabilities
security 'auto' Self-XSS warning in production only
api / alias 'makashif' / 'mk' false installs no global
once true One print per page/process
defer 'load' 'idle' or 'immediate'
respectBots true Silent for crawlers, Lighthouse, webdriver
variant 'card' 'badge' or 'floating' (card only)
scheme 'dark' 'light' or 'auto' (card only)
live true The card's FPS loop (card only)

Built for production

  • Never breaks the host app. Every console call is failure-isolated; a styling bug costs a missing line, not a white screen.
  • Free at TTI. Printing waits for load, then browser idle. Paint metrics are populated by then, so telemetry reads real numbers.
  • Degrades honestly. Chromium gets gradients, padded badges and the monogram; Firefox/Safari get colour only; anything else gets clean plaintext.
  • Readable in both console themes. %c styles accept no media queries, so a fixed palette means invisible text for half your users. The scheme is resolved at print time and the whole palette swapped — hues included, since #06b6d4 cyan on white is about 2:1 contrast. Every line clears WCAG AA in both: measured 4.76:1 minimum on light, 3.5:1 on dark.
  • No style collisions. The card lives in a shadow root, so your CSS reset and its styles cannot reach each other.
  • Quiet for robots. Silent when navigator.webdriver is set, so Lighthouse audits stay clean.
  • Battery-aware. The card's FPS loop only runs while the card is actually on screen and the tab is visible.
  • SSR-safe. Without a DOM every browser entry no-ops instead of throwing.
  • Idempotent. Immune to React StrictMode double-mounts and Fast Refresh.

CLI

npx @makashif/brand              # print the terminal banner
npx @makashif/brand init         # wire it up automatically — no app-code edits
npx @makashif/brand add          # scaffold a component (framework auto-detected)
npx @makashif/brand snippet      # print it, write nothing
npx @makashif/brand info         # resolved paths, versions, exports

init never overwrites an existing file — run it as many times as you like.

License

MIT © Muhammad Makashif

Related Packages

lostpage

Immersive 404 pages for every framework: WebGL oceans, black holes, chrome 3D ty...

473
@oyerinde/caliper

High-precision browser measurements, projections, and layout auditing

2,625 6
@passlock/browser

Flexible passkey authentication for Astro, SvelteKit, NextJS and other framework...

5,281 192
medula

Headless devtools that let a coding agent read and change the state of an open w...

1,255 124
open-wysiwyg-editor

Accessible (WCAG 2.2 AA / ATAG 2.0), RTL-first, CSP-safe rich text editor for an...

968 0

Version History

Version Released Vue License
1.0.15 >=3.3 MIT
1.0.13 >=3.3 MIT
1.0.12 >=3.3 MIT
1.0.11 >=3.3 MIT
1.0.10 >=3.3 MIT