Explain and create Sanity Studio plugins using the public plugin and tool APIs. Use when creating user-facing plugins, adding tools through plugins, or when an agent needs to understand what a Sanity plugin can configure before applying monorepo-specific default plugin wiring.
npx skills add https://github.com/sanity-io/sanity --skill sanity-plugin-authoring
A Sanity Studio plugin is a named configuration bundle that can be added to a Studio through the plugins array. Plugin configuration accepts most workspace config properties, except workspace-owned settings such as dataset, projectId, auth, and theme.
Always give plugins a stable unique name. Prefer definePlugin() so editors expose useful types and autocomplete.
import {definePlugin} from 'sanity'
export const previewUrlPlugin = definePlugin({
name: 'preview-url-plugin',
document: {
productionUrl: async (prev, {document}) => {
const slug = document.slug?.current
return slug ? `https://example.com/${slug}` : prev
},
},
})
Use definePlugin((options) => ({...})) when callers need to configure behavior.
export const myPlugin = definePlugin<{enabled?: boolean}>((options) => ({
name: 'my-plugin',
tools: options.enabled === false ? [] : [myTool],
}))
Keep option namespaces extensible. Prefer object shapes such as {feature: {enabled: true}} instead of direct booleans when future settings are likely.
Common plugin properties:
document: Document actions, badges, production URL resolvers, and new document defaults.form: Form customizations, asset sources, and custom input rendering.plugins: Nested plugins.tools: Studio tools contributed by the plugin.schema: Schema types and initial value templates.studio: Studio component overrides and middleware.i18n: Locale resource bundles used by plugin UI.title: Human-readable plugin name.onUncaughtError: Custom error handling, logging, or telemetry.Use the smallest surface that solves the feature.
A tool is a top-level Studio view with routing and predictable URLs. Tools commonly represent full-screen workflows such as Structure, Vision, Dashboard, or Presentation.
When adding a tool through a plugin:
tools property.name, title, component, and router when needed.studio.components.toolMenu when the visual menu order needs custom rendering.tools reducer pattern when changing the default opened tool, because visual menu order alone does not choose the default route.studio.components can customize parts of the Studio UI. Components that receive renderDefault are middleware: call props.renderDefault(props) unless intentionally replacing the default UI.
Use this for UI wrappers, navigation changes, or tool menu ordering. Be careful not to change scroll containers or layout ownership accidentally.
If a plugin renders UI text, add an i18n bundle instead of hard-coding user-facing strings. The usual file shape is:
feature/
├── i18n/
│ ├── index.ts
│ └── resources.ts
└── plugin/
└── index.ts
In i18n/index.ts, define a namespace and default US English bundle:
import {type LocaleResourceBundle} from '../../i18n'
export const featureNamespace: 'feature' = 'feature'
export const featureUsEnglishLocaleBundle: LocaleResourceBundle = {
locale: 'en-US',
namespace: featureNamespace,
resources: () => import('./resources'),
}
export type {FeatureLocaleResourceKeys} from './resources'
In i18n/resources.ts, export the default strings and key type:
const featureLocaleStrings = {
'action.example': 'Example',
}
export type FeatureLocaleResourceKeys = keyof typeof featureLocaleStrings
export default featureLocaleStrings
Then register the bundle from the plugin:
import {featureUsEnglishLocaleBundle} from '../i18n'
export const feature = definePlugin({
name: 'sanity/feature',
i18n: {
bundles: [featureUsEnglishLocaleBundle],
},
})
For Sanity monorepo default plugin wiring, read sanity-core-plugin after this skill.
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take sanity-io/sanity-plugin-authoring from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.