Skip to content

BlockNote codeBlock's embedded Shiki significantly increases bundle size #1487

Closed
1 of 2 issues completed
@dgd03146

Description

@dgd03146

Describe the bug
BlockNote with Shiki is causing a significant bundle size issue. Unnecessary language files (like emacs-lisp.mjs) are being included in the client bundle, increasing the bundle size by approximately 788KB (192KB gzipped).

This is occurring in a Turborepo monorepo environment with pnpm as the package manager, where our web workspace uses Next.js 14.

To Reproduce

  1. Create a Next.js 14 project (in our case, within a Turborepo monorepo)
  2. Install BlockNote: npm install @blocknote/core @blocknote/react @blocknote/mantine
  3. Create a basic BlockNote editor with code block support
  4. Run next build and analyze the bundle
  5. Notice large chunks containing Shiki language files that aren't being used

BlockNote version:

"@blocknote/core": "^0.23.6",
"@blocknote/mantine": "^0.23.6",
"@blocknote/react": "^0.23.6",

Code setup:

// BlockNote.tsx
import { BlockNoteSchema, customizeCodeBlock, defaultBlockSpecs } from '@blocknote/core';
import { BlockNoteView, useCreateBlockNote } from '@blocknote/react';

const customCodeBlock = customizeCodeBlock({
  defaultLanguage: 'typescript',
  supportedLanguages: [
    { id: 'javascript', match: ['javascript', 'js'], name: 'JavaScript' },
    { id: 'typescript', match: ['typescript', 'ts'], name: 'TypeScript' },
    { id: 'html', match: ['html'], name: 'HTML' },
    { id: 'css', match: ['css'], name: 'CSS' },
    { id: 'json', match: ['json'], name: 'JSON' },
    { id: 'markdown', match: ['markdown', 'md'], name: 'Markdown' },
  ],
});

const schema = BlockNoteSchema.create({
  blockSpecs: {
    ...defaultBlockSpecs,
    codeBlock: customCodeBlock,
  },
});

export const BlockNote = ({ initialContent }) => {
  const editor = useCreateBlockNote({
    initialContent,
    schema,
  });

  return (
    <BlockNoteView
      editor={editor}
      editable={false}
      formattingToolbar={false}
    />
  );
};

I've tried using webpack externals to exclude unnecessary language files:

// next.config.js
config.externals = [
  ...(config.externals || []),
  function(context, request, callback) {
    if (/node_modules[\/\\]@shikijs[\/\\]langs[\/\\]dist[\/\\](?!javascript|typescript|html|css|json|markdown).+\.mjs$/.test(request)) {
      console.log('Excluded Shiki language file:', request);
      return callback(null, 'commonjs {}');
    }
    callback();
  }
];

But the bundle still includes all Shiki language files:
Image

parsed: static/chunks/b9c69e33.fdaaa1746205dfd1.js (785.91 KB)
gziped: static/chunks/b9c69e33.fdaaa1746205dfd1.js (192.3 KB)

Misc

  • Node version: 22.11
  • Package manager: pnpm
  • Browser: Chrome
  • Environment: Turborepo monorepo with Next.js 14 in web workspace
  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖

Questions

  1. Is there a way to completely remove or replace Shiki in BlockNote's codeBlock?
  2. Is it possible to isolate just the code block rendering to a server component? This would keep Shiki on the server side and prevent it from being included in the client bundle.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions