Security
Wire UI takes security seriously. This page outlines our security practices and how to report vulnerabilities. The canonical disclosure policy also lives in SECURITY.md at the repository root.
Reporting Vulnerabilities
If you discover a security vulnerability in Wire UI, please report it responsibly.
Do not open a public GitHub issue for security vulnerabilities. Instead:
- Email security@wire-ui.com with a description of the vulnerability
- Include steps to reproduce the issue if possible
- Allow reasonable time for a fix before public disclosure
We aim to acknowledge reports within 48 hours and provide a fix timeline within 7 days.
Security Practices
No runtime dependencies
@wire-ui/react, @wire-ui/vue, and @wire-ui/solid all ship with zero runtime dependencies. The only peer dependency is the host framework itself (React, Vue, or SolidJS). This minimizes the attack surface — there are no transitive dependencies that could introduce supply-chain vulnerabilities.
No external resources
Wire UI makes no network requests, bundles no fonts, and loads no external assets. Components are pure JavaScript/TypeScript. This eliminates entire classes of vulnerabilities related to external resource loading and CORS.
No eval or dynamic code execution
The library never uses eval(), Function(), or any form of dynamic code execution. All code paths are statically analyzable and tree-shakeable.
XSS model: safe by default, with one opt-in raw path
Wire UI is a headless rendering library, so it is explicit about where untrusted content can flow. There are two categories.
Safe by default
All component output goes through the framework’s normal JSX/template rendering, which escapes text content automatically. In particular:
Markdownis a “bring your own parser” renderer. It walks a normalized node tree and emits elements through React/Vue/Solid — it never injects raw HTML. Text is escaped by the framework.CodeBlockrenders code as escaped text children only (it does not tokenize to HTML), so a code sample containing<script>is displayed verbatim, never executed.
URL sanitization
The default Markdown link/image renderers and the Citation footnote link run every URL through a built-in sanitizer before it reaches an href/src. URLs with executable schemes — javascript:, vbscript:, data: (except safe raster data:image/* on an <img>), and file: — are dropped, including obfuscated variants (leading whitespace, embedded control characters, mixed casing). Relative URLs, fragments, query strings, and http(s)/mailto/tel are preserved.
If you override the link or image renderers via the components map, you own sanitization for your own markup. The same helper Wire UI uses internally is exported so you can reuse it:
import { Markdown, sanitizeUrl } from '@wire-ui/react'
const components = {
link: ({ node, children }) => (
<a href={sanitizeUrl(node.url)} className="text-blue-600 underline">
{children}
</a>
),
}Opt-in raw HTML: Icon
Icon is the single component that injects raw HTML (via React’s dangerouslySetInnerHTML / the framework equivalent). It renders the inner markup of whichever SVG string you pass in its icons map:
import { Icon } from '@wire-ui/react'
import { icons } from './my-icon-set' // author-controlled SVG strings
<Icon type="search" icons={icons} />This is intentional — icon sets are static, author-controlled assets (e.g. Lucide, Heroicons). The icons map must never be built from user input. If you must render user-supplied SVG, sanitize it with a dedicated library such as DOMPurify (configured for SVG) before passing it in.
Data attributes are safe
Wire UI exposes interactive state via data-* attributes (e.g. data-hover, data-state). These are standard HTML attributes — they cannot execute code. Their values are always empty strings or predefined constants ("open", "closed", "checked", etc.), never user input.
Content Security Policy (CSP)
Wire UI works under a strict CSP. Concretely:
- No inline scripts. The library ships no
<script>tags and no inline event-handler attributes, so it needs noscript-src 'unsafe-inline'. - No
eval/ dynamic code. It never requiresscript-src 'unsafe-eval'. - No external origins. No fonts, images, or network requests, so
default-src 'self'is sufficient for Wire UI itself.
A script-src policy with neither unsafe-inline nor unsafe-eval is fully supported:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'Note on inline styles
A few components apply small inline style props for layout that cannot be expressed with data attributes alone (e.g. CodeBlock line stacking, positioned overlays in Tooltip/Popover/Sheet, computed track fills in Slider/ProgressBar). In a purely client-rendered app these are applied through the CSSOM and are not affected by style-src. If you server-render Wire UI under a strict CSP, those styles serialize to style="…" attributes, which are governed by style-src-attr (falling back to style-src). To keep style-src 'self' without 'unsafe-inline' in an SSR app, allow inline style attributes specifically:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; style-src-attr 'unsafe-inline'Inline style attributes cannot execute script, so this does not weaken your script policy.
Dependency license audit
Wire UI’s published packages are MIT-licensed and carry no runtime dependencies, so nothing beyond the host framework is distributed to your users.
| Surface | Packages | Licenses |
|---|---|---|
Shipped runtime (@wire-ui/react, @wire-ui/vue, @wire-ui/solid) | react + react-dom, vue, or solid-js (all peer) | MIT |
| Build/dev toolchain (full installed tree) | ~1,250 transitive | Permissive — MIT, ISC, Apache-2.0, BSD-2/3-Clause, BlueOak-1.0.0, 0BSD, Unlicense, CC0 — plus a few build-only weak-copyleft tools (see below) that are never bundled |
A scan of the entire installed tree finds no copyleft license in any distributed code — every published @wire-ui/* package declares "dependencies": {}, so the only license your application inherits from Wire UI is MIT. The non-permissive licenses present anywhere in the tree all belong to build- and test-time tooling that is never bundled into a published package:
@img/sharp-libvips(LGPL-3.0) — prebuilt native binary for image optimization in the docs/Storybook build.lightningcss,axe-core(MPL-2.0) anddompurify(dual MPL-2.0 OR Apache-2.0) — CSS transform, accessibility test runner, and SVG sanitizer used by the toolchain/tests.
MPL-2.0 and LGPL are file-level copyleft that only attaches to their own source; because none of these packages ship in a Wire UI artifact, they impose no obligation on your application. A handful of packages omit the SPDX license field in their metadata; their LICENSE files confirm they are MIT.
Because each published package declares "dependencies": {} and lists only the framework as a peer, the license surface your application inherits from Wire UI is just MIT.
Third-Party Dependencies
@wire-ui/react
| Dependency | Type | Purpose |
|---|---|---|
react | peer | React 19+ |
react-dom | peer | React DOM 19+ |
No runtime dependencies — only peer dependencies.
@wire-ui/vue
| Dependency | Type | Purpose |
|---|---|---|
vue | peer | Vue 3.5+ |
No runtime dependencies — only peer dependencies.
@wire-ui/solid
| Dependency | Type | Purpose |
|---|---|---|
solid-js | peer | SolidJS 1.9+ |
No runtime dependencies — only peer dependencies.
@wire-ui/mcp
| Dependency | Type | Purpose |
|---|---|---|
@modelcontextprotocol/sdk | runtime | MCP protocol implementation |
zod | runtime | Input validation for MCP tools |
The MCP server is a development tool and is not included in your production bundle.
Supported Versions
Security fixes are applied to the latest minor version only. We recommend always using the latest version of Wire UI.
| Version | Supported |
|---|---|
| Latest | Yes |
| Older | No |