
Security News
Critical Security Vulnerability in React Server Components
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.
@tapestrylab/resolve
Advanced tools
Unified system for resolving component, docs, and dependency references across the Tapestry ecosystem
Unified system for resolving component, docs, and dependency references across the Tapestry ecosystem
The @tapestrylab/resolve package provides a flexible, plugin-based resolution system for locating modules, components, and dependencies. It abstracts away where things live—whether in a local filesystem, fetched from a CDN, or retrieved from a remote registry.
Perfect for:
@ui/Button) to actual paths@tapestrylab/extract for props, types, and JSDocpnpm add @tapestrylab/resolve
import { createResolver, strategies } from "@tapestrylab/resolve"
const resolver = createResolver({
strategies: [
// Try local files first
strategies.local({
root: "/src",
alias: {
"@ui": "components/ui",
"@core": "components/core",
},
}),
// Fall back to CDN for npm packages
strategies.cdn({
provider: "esm.sh",
versionMap: {
react: "18.3.1",
},
}),
],
})
// Resolve a local component
const button = await resolver.resolve("@ui/Button")
console.log(button)
// { id: '@ui/Button', path: '/src/components/ui/Button.tsx', source: 'local' }
// Resolve an npm package
const react = await resolver.resolve("react")
console.log(react)
// { id: 'react', path: 'https://esm.sh/react@18.3.1', source: 'cdn' }
import { createComponentResolver, strategies } from '@tapestrylab/resolve';
const docResolver = createComponentResolver({
strategies: [
strategies.local({
root: '/src',
alias: { '@ui': 'components/ui' }
})
]
});
// Resolve component documentation with SSR preview and sandbox config
const docs = await docResolver.resolve({
entry: '/src/components/Button.tsx',
renderPreview: true, // Generate SSR HTML preview
sandbox: true // Generate sandbox configuration
});
console.log(docs);
// {
// name: "Button",
// description: "A customizable button component",
// filePath: "/src/components/Button.tsx",
// props: [
// {
// name: "variant",
// type: "'primary' | 'secondary'",
// required: false,
// defaultValue: "'primary'"
// }
// ],
// previewHtml: "<div class=\"tapestry-preview\">...</div>",
// sandbox: {
// code: "...",
// dependencies: { "react": "latest" },
// files: { "Button.tsx": "...", "App.tsx": "..." }
// }
// }
createResolver(config)Create a new module resolver instance.
const resolver = createResolver({
strategies: [strategies.local(), strategies.cdn()],
cache: true, // Enable caching (default: true)
context: {
root: "/project",
metadata: {
/* custom data */
},
},
})
resolver.resolve(id, context?)Resolve a single module identifier.
const result = await resolver.resolve("@ui/Button")
// Returns: ResolvedEntry | null
const result = await resolver.resolve("./Button", {
importer: "/src/components/index.ts",
})
resolver.resolveMany(ids, context?)Resolve multiple identifiers in parallel.
const results = await resolver.resolveMany(["@ui/Button", "@ui/Input", "react", "lodash/debounce"])
// Returns: Map<string, ResolvedEntry | null>
resolver.clearCache()Clear all cached resolutions.
resolver.clearCache()
resolver.addStrategy(strategy, prepend?)Add a new strategy dynamically.
resolver.addStrategy(strategies.remote(), false) // Add to end
resolver.addStrategy(strategies.local(), true) // Add to beginning
createComponentResolver(config, options?)Create a component documentation resolver.
const docResolver = createComponentResolver(
{
strategies: [strategies.local({ root: '/src' })]
},
{
renderFunction: (component, props) => {
// Custom SSR rendering logic
return customRender(component, props);
}
}
);
docResolver.resolve(options)Resolve component documentation with optional SSR preview and sandbox config.
const docs = await docResolver.resolve({
entry: '/src/components/Button.tsx',
renderPreview: true, // Generate SSR HTML preview
sandbox: true, // Generate sandbox configuration
previewProps: { // Props to pass during preview render
variant: 'primary'
}
});
// Returns: ComponentDoc
// {
// name: string;
// description?: string;
// filePath: string;
// props?: PropDoc[];
// examples?: ExampleDoc[];
// imports?: string[];
// previewHtml?: string;
// sandbox?: SandboxConfig;
// }
docResolver.resolveMany(entries, options?)Resolve multiple components in parallel.
const allDocs = await docResolver.resolveMany(
['/src/components/Button.tsx', '/src/components/Input.tsx'],
{ renderPreview: true, sandbox: true }
);
Resolves local filesystem paths with alias support.
strategies.local({
root: "/project/src",
alias: {
"@ui": "components/ui",
"@core": "components/core",
"@utils": "lib/utils",
},
extensions: [".ts", ".tsx", ".js", ".jsx"],
checkExists: true, // Set to false for browser environments
})
Features:
@ui/Button → components/ui/Button)./Button, ../utils/helper)/usr/local/lib/module).ts, .tsx, .js, .jsx)./components → ./components/index.ts)Resolves npm packages from CDN providers.
strategies.cdn({
provider: "esm.sh", // or 'jsdelivr', 'unpkg'
versionMap: {
react: "18.3.1",
"react-dom": "18.3.1",
"@radix-ui/react-popover": "1.0.7",
},
verifyAvailability: true, // Check with HEAD request
timeout: 5000, // Timeout for availability check (ms)
})
Providers:
esm.sh (default): Modern ESM CDNjsdelivr: Fast, reliable CDNunpkg: Popular npm CDNFeatures:
@radix-ui/react-popover)lodash/debounce)versionMapCreate your own resolution strategy:
import type { ResolverStrategy } from "@tapestrylab/resolve"
const myStrategy: ResolverStrategy = {
name: "my-custom-strategy",
async resolve(id: string, context?) {
// Your custom resolution logic
if (shouldResolve(id)) {
return {
id,
path: "/resolved/path",
source: "local",
}
}
return null // Pass to next strategy
},
}
const resolver = createResolver({
strategies: [myStrategy, strategies.cdn()],
})
Resolve user-uploaded components and npm dependencies in the browser:
const resolver = createResolver({
strategies: [
// User's uploaded components (in-memory filesystem)
strategies.local({
root: "/playground/uploads",
checkExists: false, // Browser environment
alias: {
"@ui": "components/ui",
},
}),
// External dependencies from CDN
strategies.cdn({
provider: "esm.sh",
verifyAvailability: false, // Skip for faster resolution
}),
],
})
// User imports in their code
const userButton = await resolver.resolve("@ui/Button")
const radix = await resolver.resolve("@radix-ui/react-popover")
Resolve internal packages and external dependencies:
const resolver = createResolver({
strategies: [
strategies.local({
root: "/monorepo",
alias: {
"@company/ui": "packages/ui/src",
"@company/core": "packages/core/src",
},
}),
],
})
const component = await resolver.resolve("@company/ui/Button")
interface ResolvedEntry {
id: string // Original identifier
path: string // Resolved path or URL
source?: "local" | "cdn" | "remote"
}
interface ResolutionContext {
root?: string // Project root
importer?: string // Current file (for relative imports)
metadata?: Record<string, unknown>
}
interface ResolverStrategy {
name: string
resolve(id: string, context?: ResolutionContext): Promise<ResolvedEntry | null>
}
resolveMany() resolves multiple identifiers concurrentlyThe package works in both Node.js and browser environments. For browser usage:
const resolver = createResolver({
strategies: [
strategies.local({
checkExists: false, // Disable filesystem checks
}),
strategies.cdn({
verifyAvailability: false, // Optional: skip HEAD requests
}),
],
})
# Install dependencies
pnpm install
# Build the package
pnpm build
# Run tests
pnpm test
# Run tests in watch mode
pnpm dev
# Type check
pnpm type-check
# Try the interactive demo
pnpm demo
The package includes an interactive demo script that showcases all resolver features using real fixtures:
pnpm demo
This will demonstrate:
See scripts/README.md for more details.
MIT
FAQs
Unified system for resolving component, docs, and dependency references across the Tapestry ecosystem
We found that @tapestrylab/resolve demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
React disclosed a CVSS 10.0 RCE in React Server Components and is advising users to upgrade affected packages and frameworks to patched versions now.

Research
/Security News
We spotted a wave of auto-generated “elf-*” npm packages published every two minutes from new accounts, with simple malware variants and early takedowns underway.

Security News
TypeScript 6.0 will be the last JavaScript-based major release, as the project shifts to the TypeScript 7 native toolchain with major build speedups.