// vite.config.js
export default 
  root: 'web/themes/custom/my_theme',
  build: 
    rollupOptions: 
      input: 
        main: 'web/themes/custom/my_theme/src/main.js',
        editor: 'web/themes/custom/my_theme/src/editor.js',
      ,
      output: 
        dir: 'web/themes/custom/my_theme/dist',
      ,
    ,
  ,
  server: 
    origin: 'https://my-d10-site.ddev.site',
    port: 3000,
  ,
;

| Feature | Drupal 7 (Legacy) | Drupal 9 (Transition) | Drupal 10 (Modern) | |---------|------------------|------------------------|--------------------| | Template engine | PHP templates | Twig 2 | Twig 3 | | CSS/JS | Info file + drupal_add_css | Libraries + Attachments | Libraries + Asset injection | | Components | None (partials only) | UI Patterns (contributed) | SDC (core experimental -> stable) | | Build process | None / manual | Webpack (custom) | Vite / ES modules | | Decoupled | JSON export modules | JSON:API contrib | JSON:API core + optional Next.js |


Instead of loading all CSS/JS globally, attach libraries only to the specific components rendered on the page. Drupal 10’s lazy-loading ensures that if a card component isn't on the page, its CSS isn't downloaded.


Google’s Core Web Vitals penalizes render-blocking CSS and large JS bundles. Modern Drupal 10 theming uses critical CSS extraction and lazy loading, impossible without a modern build toolchain.

Download the PDF for a side-by-side comparison chart of legacy vs. modern theme structures (Page 3).