Package Exports
- @viscalyx/developer-mode-core
- @viscalyx/developer-mode-core/noop
- @viscalyx/developer-mode-core/package.json
Readme
@viscalyx/developer-mode-core
Framework-agnostic Developer Mode utilities for marker-backed UI discovery, stable naming, copy payload generation, and viewport scanning.
Overview
@viscalyx/developer-mode-core is the low-level package behind the
Developer Mode overlay. It does not render any UI. Instead, it provides the
shared contract that host applications and UI runtimes use to:
- emit curated
data-developer-mode-*markers - normalize marker text and values
- scan visible DOM targets
- resolve the best target under the pointer
- build deterministic chip labels and copy payloads
- detect the Developer Mode keyboard shortcut
Use this package when you want a reusable naming layer that can be consumed by an overlay, inspector, test helper, or custom debugging tool.
When To Use This Package
Use @viscalyx/developer-mode-core when you need one or more of these
capabilities:
- a stable marker API for important UI surfaces
- deterministic copy text such as
requirements table > column header: requirement id - a consistent keyboard shortcut contract for toggling developer tooling
- DOM scanning helpers that prefer curated markers but can fall back to semantic roles and stable labels
- a no-op marker helper for production builds that should not emit marker attributes
If you also want a ready-made React overlay, use this package together with
@viscalyx/developer-mode-react.
Installation
npm install --save-dev @viscalyx/developer-mode-coreCurrent Repo Usage
In this repository, the package is currently consumed as a local
devDependency:
"@viscalyx/developer-mode-core": "file:packages/developer-mode-core"App code does not import the package directly from every component. Instead, it routes marker creation through a small host adapter:
That pattern is recommended for future consumers too, because it gives the host application one place to centralize naming conventions, helper wrappers, and future no-op behavior.
Quick Start
1. Mark important UI surfaces
import { devMarker } from '@viscalyx/developer-mode-core'
export function RequirementsHeader() {
return (
<button
{...devMarker({
context: 'requirements table',
name: 'column header',
value: 'requirement id',
priority: 500,
})}
type="button"
>
Requirement ID
</button>
)
}When Developer Mode is enabled, devMarker(...) emits curated
data-developer-mode-* attributes. When the package is aliased to its
./noop entrypoint, the same call returns {} so production HTML stays clean.
2. Resolve visible targets
import {
findDeveloperModeTargetAt,
scanVisibleDeveloperModeTargets,
} from '@viscalyx/developer-mode-core'
const hoveredTarget = findDeveloperModeTargetAt(event.target as HTMLElement)
const visibleTargets = scanVisibleDeveloperModeTargets(document.body)3. Build stable copy text
import { buildDeveloperModeCopyText } from '@viscalyx/developer-mode-core'
const payload = buildDeveloperModeCopyText({
context: 'requirements table',
name: 'column header',
value: 'requirement id',
})
// "requirements table > column header: requirement id"Marker API
The main authoring API is devMarker(...).
devMarker({
name: 'column header',
context: 'requirements table',
value: 'requirement id',
priority: 500,
})Supported input fields:
name: required canonical English labelcontext: optional English parent contextvalue: optional English or runtime valuepriority: optional numeric override used to win collisions
When enabled, the helper emits:
data-developer-mode-namedata-developer-mode-contextdata-developer-mode-valuedata-developer-mode-priority
The package also exports:
noopDevMarker(): always returns{}normalizeDeveloperModeText(value): collapses whitespace and removes empty strings
API Overview
This package intentionally exposes a small practical surface:
devMarker(...)andnoopDevMarker()for DOM authoringbuildDeveloperModeCopyText(...)for deterministic copied referencesbuildDeveloperModeChipLabel(...)for compact overlay labelsmatchesDeveloperModeShortcut(...)plus shortcut constants for keyboard activationisEditableTarget(...)to ignore toggles inside inputs and editable regionsfindDeveloperModeTargetAt(...)to resolve the best target from a hovered DOM elementscanVisibleDeveloperModeTargets(...)to scan the viewport for visible targets- shared types such as
DeveloperModeDescriptor,DeveloperModeTarget, andDeveloperModeMarkerInput
Scanning And Fallback Behavior
The scanner prefers curated markers first, then falls back to a bounded set of generic heuristics.
Priority order:
- explicit
data-developer-mode-*markers - known product hooks such as
data-floating-action-rail - semantic roles such as
dialog,tab,tabpanel, andnavigation aria-labelandtitle- stable visible text
data-testid
The scanner only returns targets that are currently visible in the viewport and skips:
- hidden or
aria-hiddennodes - zero-sized elements
- offscreen elements
- the Developer Mode overlay itself
Shortcut Contract
The package exports the shared shortcut constants:
DEVELOPER_MODE_SHORTCUT_LABEL:Mod+Alt+Shift+HDEVELOPER_MODE_SHORTCUT_KEY:hDEVELOPER_MODE_SHORTCUT_CODE:KeyH
Use matchesDeveloperModeShortcut(...) instead of comparing raw key values
yourself. It accepts either the physical KeyH code or a matching lowercase
key, which keeps the shortcut stable even when modifier keys alter the typed
character on some keyboard layouts.
No-Op And Production Exclusion
The package exposes a ./noop entrypoint for builds that should keep the call
sites but remove the marker output:
import { devMarker } from '@viscalyx/developer-mode-core/noop'In practice, most applications should not import ./noop directly from
components. Instead, configure a build-time alias so the main package resolves
to ./noop in production or other non-debug builds.
In this repository:
- local development uses the real package
- non-development builds alias the package to
packages/developer-mode-core/src/noop.tsunlessENABLE_DEVELOPER_MODE=true
See Developer Mode Overlay for the repo-specific build wiring.
Used Together With @viscalyx/developer-mode-react
@viscalyx/developer-mode-core provides the contract and scanning logic.
@viscalyx/developer-mode-react provides the visible overlay and interaction
layer.
Typical division of responsibility:
- core:
- marker helpers
- target discovery
- copy text and chip label formatting
- shortcut matching
- react:
- provider lifecycle
- pointer tracking
- portal rendering
- copy toast and overlay chip UI
Minimal combined example:
import { devMarker } from '@viscalyx/developer-mode-core'
import DeveloperModeProvider from '@viscalyx/developer-mode-react'
export function AppShell({ children }: { children: React.ReactNode }) {
return (
<DeveloperModeProvider
labels={{
badge: 'Developer Mode',
copied: 'Copied',
copyFailed: 'Copy failed',
}}
>
<main {...devMarker({ name: 'main content' })}>{children}</main>
</DeveloperModeProvider>
)
}For a fuller React integration guide, see
packages/developer-mode-react/README.md.
Notes For Host Applications
- Keep curated labels in English, even if the product UI is localized.
- Prefer a host-side adapter such as
lib/developer-mode-markers.tsso app code does not hardcode package-specific policy everywhere. - Use curated markers for important product surfaces first, then rely on fallback scanning only for generic coverage.
- Keep copied payloads deterministic. A stable
context > name: valueformat makes prompts and support notes much easier to reuse. - Treat
priorityas an escape hatch. Use it only when two nearby candidates would otherwise compete for the same overlay region.