Skip to content

Comparison: Plugin vs Native ​

Sanity Structure Tool is designed to eliminate the repetitive boilerplate required by the native Sanity Structure Builder. This guide demonstrates the code reduction and clarity gained by switching to a declarative approach.

Standard Desk Hierarchy ​

In a typical studio, you often need to handle singletons (like "Settings"), dividers, and standard document lists.

ts
const listItems = defineListItems([
  {
    title: 'Site Settings',
    schemaType: 'settings',
    // Automatically handles id and editor view
    singleton: true,
  },
  {
    isDivider: true,
  },
  {
    // Automatically pluralizes title and adds icon
    schemaType: 'post',
  },
]);
ts
const listItems = defineListItems([
  // Automatically handles id and editor view
  helpers.singleton('settings', {
    title: 'Site Settings',
  }),
  helpers.divider(),
  // Automatically pluralizes title and adds icon
  helpers.listing('post'),
]);
ts
export const structure = (S) =>
  S.list()
    .title('Desk')
    .items([
      // 1. Singletons require manual id and child definition
      S.listItem()
        .title('Site Settings')
        .id('settings')
        .child(S.document().schemaType('settings').documentId('settings')),

      S.divider(),

      // 2. Standard items require explicit list item calls
      S.documentTypeListItem('post').title('Posts'),
    ]);

Access Control (Workspaces & Roles) ​

Managing visibility based on user roles or workspaces is where the native API becomes extremely repetitive.

ts
// Automatically handles logic for both roles and workspaces
const listItems = defineListItems([
  {
    schemaType: 'revenue',
    workspaces: ['staging'],
    roles: ['administrator'],
  },
]);
ts
const listItems = defineListItems([
  helpers.listing('revenue', {
    workspaces: ['staging'],
    roles: ['administrator'],
  }),
]);
ts
export const structure = (S, context) => {
  const { currentUser, dataset } = context;
  const isAdmin = currentUser.roles.some((r) => r.name === 'administrator');
  const items = [];

  // Manual filtering logic for every protected item
  if (isAdmin && dataset === 'staging') {
    items.push(S.documentTypeListItem('revenue'));
  }

  return S.list().title('Desk').items(items);
};

Key Advantages ​

FeatureSanity Structure ToolNative Builder
SyntaxDeclarative (JSON like)Imperative (Method Chaining)
SingletonsOne property (singleton: true)Manual setup (id, view, actions)
Type SafetyContextual & TypedGeneric
BoilerplateMinimalHigh (repeats for every item)
Roles/WorkspacesBuilt-in protectionManual if/else logic

Summary ​

By using the Sanity Structure Tool, you trade complex method chaining for a clean, typed configuration. This not only reduces the amount of code you write but also makes your structure easier to read, maintain, and protect.

Released under the MIT License.