Theming

Theming

SynclineMDX Editor is fully themeable via CSS custom properties. Override any --smdx-* variable to match your brand — no build step required.

Theme via Config

Pass a theme object (CSS variable map) to createEditor():

editor.ts

import { createEditor } from '@synclineapi/mdx-editor';
import '@synclineapi/mdx-editor/style.css';

// Theme is a Record<string, string> of CSS custom properties.
// Keys can include the '--' prefix or just the property name
// (--smdx- prefix is added automatically if missing).

const editor = createEditor({
  container: '#editor',
  theme: {
    '--smdx-primary': '#e11d48',
    '--smdx-radius': '12px',
    '--smdx-font-size': '16px',
  },
});

Dark Mode

Dark mode is toggled by adding the .smdx-dark CSS class to the editor root or any parent element. The package ships with a built-in dark palette:

Light (default)

Dark (.smdx-dark)

dark-theme.css

/* Dark mode is activated via the .smdx-dark CSS class.
   Add it to the editor container or a parent element. */

/* Built-in dark palette — applied automatically: */
.smdx-editor.smdx-dark,
.smdx-dark .smdx-editor {
  --smdx-primary: #818cf8;
  --smdx-primary-hover: #6366f1;
  --smdx-bg: #1e1e2e;
  --smdx-bg-muted: #2a2a3c;
  --smdx-text: #e2e8f0;
  --smdx-text-muted: #94a3b8;
  --smdx-border: #374151;
  --smdx-border-focus: #818cf8;
  --smdx-toolbar-btn-active-bg: #312e81;
}

Toggle with JavaScript

dark-mode.ts

// Toggle dark mode by adding/removing the .smdx-dark class:
const root = editor.getRoot(); // returns the .smdx-editor element

// Enable dark mode
root.classList.add('smdx-dark');

// Disable dark mode
root.classList.remove('smdx-dark');

// Match system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
if (prefersDark.matches) root.classList.add('smdx-dark');
prefersDark.addEventListener('change', (e) => {
  root.classList.toggle('smdx-dark', e.matches);
});

All CSS Variables

All design tokens are defined as CSS custom properties on .smdx-editor:

editor.css

/* Override any --smdx-* variable on .smdx-editor or a parent. */
.smdx-editor {
  /* Colors */
  --smdx-primary: #6366f1;
  --smdx-primary-hover: #4f46e5;
  --smdx-bg: #ffffff;
  --smdx-bg-muted: #f8fafc;
  --smdx-text: #1e293b;
  --smdx-text-muted: #64748b;
  --smdx-border: #e2e8f0;
  --smdx-border-focus: #6366f1;

  /* Typography */
  --smdx-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --smdx-font-mono: 'SF Mono', 'Fira Code', Consolas, monospace;
  --smdx-font-size: 14px;
  --smdx-line-height: 1.6;

  /* Layout */
  --smdx-radius: 8px;
  --smdx-radius-sm: 4px;
  --smdx-spacing-xs: 4px;
  --smdx-spacing-sm: 8px;
  --smdx-spacing-md: 12px;
  --smdx-spacing-lg: 16px;
  --smdx-spacing-xl: 24px;

  /* Toolbar */
  --smdx-toolbar-bg: var(--smdx-bg);
  --smdx-toolbar-border: var(--smdx-border);
  --smdx-toolbar-btn-size: 32px;
  --smdx-toolbar-btn-radius: 6px;
  --smdx-toolbar-btn-hover-bg: var(--smdx-bg-muted);
  --smdx-toolbar-btn-active-bg: #eef2ff;
  --smdx-toolbar-btn-active-color: var(--smdx-primary);

  /* Editor & Preview */
  --smdx-editor-bg: var(--smdx-bg);
  --smdx-editor-text: var(--smdx-text);
  --smdx-preview-bg: var(--smdx-bg);
  --smdx-preview-text: var(--smdx-text);

  /* Status bar */
  --smdx-statusbar-bg: var(--smdx-bg-muted);
  --smdx-statusbar-text: var(--smdx-text-muted);

  /* Shadows */
  --smdx-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --smdx-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08);
  --smdx-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12);
}

Brand Theme

Only override the tokens you need:

brand.css

/* Brand theme example — override only what you need */
.smdx-editor {
  --smdx-primary: #9333ea;
  --smdx-primary-hover: #7c3aed;
  --smdx-border-focus: #9333ea;
  --smdx-toolbar-btn-active-color: #9333ea;
  --smdx-font-family: 'Outfit', sans-serif;
  --smdx-radius: 12px;
}

React Integration

Use useRef + useEffect to mount the editor and toggle dark mode reactively:

ThemedEditor.tsx

'use client';

import { useRef, useEffect } from 'react';
import { createEditor } from '@synclineapi/mdx-editor';
import '@synclineapi/mdx-editor/style.css';

export function ThemedEditor({ darkMode }: { darkMode: boolean }) {
  const containerRef = useRef<HTMLDivElement>(null);
  const editorRef = useRef<ReturnType<typeof createEditor>>();

  useEffect(() => {
    if (!containerRef.current) return;
    editorRef.current = createEditor({
      container: containerRef.current,
      theme: { '--smdx-primary': '#9333ea' },
    });
    return () => editorRef.current?.destroy();
  }, []);

  useEffect(() => {
    const root = editorRef.current?.getRoot();
    if (root) root.classList.toggle('smdx-dark', darkMode);
  }, [darkMode]);

  return <div ref={containerRef} />;
}

CSS Variable Reference

VariableLightDarkDescription
--smdx-primary
#6366f1
#818cf8

Accent / brand colour

--smdx-primary-hover
#4f46e5
#6366f1

Accent hover state

--smdx-bg
#ffffff
#1e1e2e

Overall editor background

--smdx-bg-muted
#f8fafc
#2a2a3c

Muted surface background

--smdx-text
#1e293b
#e2e8f0

Primary text colour

--smdx-text-muted
#64748b
#94a3b8

Secondary / muted text

--smdx-border
#e2e8f0
#374151

Border and divider colour

--smdx-border-focus
#6366f1
#818cf8

Focus ring colour

--smdx-font-family
system-ui
system-ui

UI and prose font

--smdx-font-mono
monospace
monospace

Code font family

--smdx-font-size
14px
14px

Base font size

--smdx-radius
8px
8px

Border radius for elements

--smdx-toolbar-btn-size
32px
32px

Toolbar button size

SynclineMDX

© 2026 SynclineMDX Editor. All rights reserved.