6 Guide to migrate to tree shaking structure
RitvikSardana edited this page 2025-11-24 17:48:57 +05:30

Overview

We used to import all our components from the root index file. There was no way for bundlers (vite) to tree shake unused code. This led to larger bundle sizes and performance issues. PR

Available imports / sub-paths

  • frappe-ui - Most commonly used components, composables, types & utilities.
  • frappe-ui/frappe - All components, composables & utilities related to Frappe Apps.
  • frappe-ui/icons - All icons exported from Frappe UI, can be found here.

frappe-ui configuration imports

  • frappe-ui/tailwind - Tailwind preset for Frappe UI. Import it in your tailwind.config.js
  • frappe-ui/vite - Vite configuration for Frappe UI. Import it in your vite.config file
  • frappe-ui/style.css - Global styles for Frappe UI. Import it in your main CSS file
  • frappe-ui/tsconfig.base.json - Base tsconfig for Frappe UI. Extend it in your tsconfig.json. This file configures how the TS compiler will behave. Provides this via "compilerOptions". Can be extended in your project's tsconfig.json. To override specific options, you can specify them in your tsconfig.json file of your app.

Migration steps

  1. Change imports like

import Badge from "frappe-ui/src/components/Badge/Badge.vue" to import { Badge } from "frappe-ui"

Most of the nested imports will be covered like this. If by chance some file / function is missed, please raise an issue or add that file into root index.ts file.

Checkout this section to see the changed imports.

  1. Import all icons from frappe-ui/icons

  2. In tailwind.config.js, change

import frappeUIPreset from "frappe-ui/src/tailwind/preset"; to import frappeUIPreset from "frappe-ui/tailwind";

  1. In your index.css or main css file, change

@import "frappe-ui/src/style.css"; to @import "frappe-ui/style.css";

  1. For ts projects, frappe-ui now provides a base tsconfig. To use it, extend it in your tsconfig.json like this
{
  "extends": "frappe-ui/tsconfig.base.json",
  "compilerOptions": {
	// your overrides here
  }
}

Results

All apps using frappe-ui should see a significant reduction in bundle size almost 2.5x times.

Local site testing:

App name Before After Times
Helpdesk 2540 KBs 816KBs ~3x
CRM ~2450 KBs ~620KBs ~4x
Drive ~3000 KBs ~1200 KBs ~3x

Production site testing:

Before image

After image

793 KBs to 227 KBs ~2.5x reduction in bundle size

Changes to make

1. Components

  • import LoadingIndicator from "frappe-ui/src/components/LoadingIndicator.vue" → import { LoadingIndicator } from 'frappe-ui'

  • import Input from "frappe-ui/src/components/Input.vue" → import { Input } from 'frappe-ui'

  • import Popover from 'frappe-ui/src/components/Popover.vue' → import { Popover } from 'frappe-ui'

  • import ConfirmDialog from 'frappe-ui/src/components/ConfirmDialog.vue' → import { ConfirmDialog } from 'frappe-ui'

  • import TextInput from 'frappe-ui/src/components/TextInput/TextInput.vue' → import { TextInput } from 'frappe-ui'

  • import DatePicker from 'frappe-ui/src/components/DatePicker/DatePicker.vue' → import { DatePicker } from 'frappe-ui'

  • import FormLabel from "frappe-ui/src/components/FormLabel.vue" → import { FormLabel } from 'frappe-ui'

2. Utils

  • import { useDoctype } from 'frappe-ui/src/data-fetching' → import { useDoctype } from 'frappe-ui'

  • import { useNewDoc } from 'frappe-ui/src/data-fetching' → import { useNewDoc } from 'frappe-ui'

  • import { useFileUpload } from 'frappe-ui/src/utils/useFileUpload' → import { useFileUpload } from 'frappe-ui'

  • import { useCall } from 'frappe-ui/src/data-fetching' → import { useCall } from 'frappe-ui'

  • import FileUploadHandler from 'frappe-ui/src/utils/fileUploadHandler' → import { FileUploadHandler } from 'frappe-ui'

3. Types

  • import { UseListOptions } from 'frappe-ui/src/data-fetching/useList/types' → import { UseListOptions } from 'frappe-ui'

  • import type { OrderBy } from 'frappe-ui/src/data-fetching/useList/types' → import type { OrderBy } from 'frappe-ui'

  • import { ImageExtension } from 'frappe-ui/src/components/TextEditor/extensions/image' → import { ImageExtension } from 'frappe-ui'

4. Icons

  • import CircleCheck from 'frappe-ui/src/icons/CircleCheck.vue' → import { CircleCheckIcon } from 'frappe-ui/icons'

  • import HelpIcon from "frappe-ui/frappe/Icons/HelpIcon.vue" → import { HelpIcon } from "frappe-ui/icons"