diff --git a/eslint-local-rules/index.js b/eslint-local-rules/index.js
index 9348706399..d9d894c33e 100644
--- a/eslint-local-rules/index.js
+++ b/eslint-local-rules/index.js
@@ -41,12 +41,11 @@ module.exports = {
           if (
             /^@budibase\/[^/]+\/.*$/.test(importPath) &&
             importPath !== "@budibase/backend-core/tests" &&
-            importPath !== "@budibase/string-templates/test/utils" &&
-            importPath !== "@budibase/client/manifest.json"
+            importPath !== "@budibase/string-templates/test/utils"
           ) {
             context.report({
               node,
-              message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests, @budibase/string-templates/test/utils and @budibase/client/manifest.json.`,
+              message: `Importing from @budibase is not allowed, except for @budibase/backend-core/tests and @budibase/string-templates/test/utils.`,
             })
           }
         },
diff --git a/lerna.json b/lerna.json
index c16b958d24..15f405c847 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,6 +1,6 @@
 {
   "$schema": "node_modules/lerna/schemas/lerna-schema.json",
-  "version": "3.3.5",
+  "version": "3.3.6",
   "npmClient": "yarn",
   "concurrency": 20,
   "command": {
diff --git a/packages/builder/src/helpers/duplicate.ts b/packages/builder/src/helpers/duplicate.ts
index b4740b3e52..eb705c6525 100644
--- a/packages/builder/src/helpers/duplicate.ts
+++ b/packages/builder/src/helpers/duplicate.ts
@@ -76,13 +76,15 @@ export const getSequentialName = <T extends any>(
   {
     getName,
     numberFirstItem,
+    separator = "",
   }: {
     getName?: (item: T) => string
     numberFirstItem?: boolean
+    separator?: string
   } = {}
 ) => {
   if (!prefix?.length) {
-    return null
+    return ""
   }
   const trimmedPrefix = prefix.trim()
   const firstName = numberFirstItem ? `${prefix}1` : trimmedPrefix
@@ -107,5 +109,5 @@ export const getSequentialName = <T extends any>(
       max = num
     }
   })
-  return max === 0 ? firstName : `${prefix}${max + 1}`
+  return max === 0 ? firstName : `${prefix}${separator}${max + 1}`
 }
diff --git a/packages/builder/src/helpers/screen.ts b/packages/builder/src/helpers/screen.ts
deleted file mode 100644
index 24988c2195..0000000000
--- a/packages/builder/src/helpers/screen.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { Component, Screen, ScreenProps } from "@budibase/types"
-import clientManifest from "@budibase/client/manifest.json"
-
-export function findComponentsBySettingsType(
-  screen: Screen,
-  type: string | string[]
-) {
-  const typesArray = Array.isArray(type) ? type : [type]
-
-  const result: {
-    component: Component
-    setting: {
-      type: string
-      key: string
-    }
-  }[] = []
-  function recurseFieldComponentsInChildren(component: ScreenProps) {
-    if (!component) {
-      return
-    }
-
-    const definition = getManifestDefinition(component)
-    const setting =
-      "settings" in definition &&
-      definition.settings.find((s: any) => typesArray.includes(s.type))
-    if (setting && "type" in setting) {
-      result.push({
-        component,
-        setting: { type: setting.type!, key: setting.key! },
-      })
-    }
-    component._children?.forEach(child => {
-      recurseFieldComponentsInChildren(child)
-    })
-  }
-
-  recurseFieldComponentsInChildren(screen?.props)
-  return result
-}
-
-export function getManifestDefinition(component: Component | string) {
-  const componentType =
-    typeof component === "string"
-      ? component
-      : component._component.split("/").slice(-1)[0]
-  const definition =
-    clientManifest[componentType as keyof typeof clientManifest]
-  return definition
-}
diff --git a/packages/builder/src/helpers/tests/duplicate.test.ts b/packages/builder/src/helpers/tests/duplicate.test.ts
index 131e76a6c2..5e956d7b1c 100644
--- a/packages/builder/src/helpers/tests/duplicate.test.ts
+++ b/packages/builder/src/helpers/tests/duplicate.test.ts
@@ -49,7 +49,7 @@ describe("getSequentialName", () => {
 
   it("handles nullish prefix", async () => {
     const name = getSequentialName([], null)
-    expect(name).toBe(null)
+    expect(name).toBe("")
   })
 
   it("handles just the prefix", async () => {
diff --git a/packages/builder/src/stores/builder/components.ts b/packages/builder/src/stores/builder/components.ts
index 90e1abfecf..f0dbc560c1 100644
--- a/packages/builder/src/stores/builder/components.ts
+++ b/packages/builder/src/stores/builder/components.ts
@@ -20,6 +20,7 @@ import {
   previewStore,
   tables,
   componentTreeNodesStore,
+  screenComponents,
 } from "@/stores/builder"
 import { buildFormSchema, getSchemaForDatasource } from "@/dataBinding"
 import {
@@ -37,6 +38,7 @@ import {
   Table,
 } from "@budibase/types"
 import { utils } from "@budibase/shared-core"
+import { getSequentialName } from "@/helpers/duplicate"
 
 interface Component extends ComponentType {
   _id: string
@@ -60,6 +62,7 @@ export interface ComponentDefinition {
   features?: Record<string, boolean>
   typeSupportPresets?: Record<string, any>
   legalDirectChildren: string[]
+  requiredAncestors?: string[]
   illegalChildren: string[]
 }
 
@@ -452,7 +455,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
    * @returns
    */
   createInstance(
-    componentName: string,
+    componentType: string,
     presetProps: any,
     parent: any
   ): Component | null {
@@ -461,11 +464,20 @@ export class ComponentStore extends BudiStore<ComponentState> {
       throw "A valid screen must be selected"
     }
 
-    const definition = this.getDefinition(componentName)
+    const definition = this.getDefinition(componentType)
     if (!definition) {
       return null
     }
 
+    const componentName = getSequentialName(
+      get(screenComponents),
+      `New ${definition.friendlyName || definition.name}`,
+      {
+        getName: c => c._instanceName,
+        separator: " ",
+      }
+    )
+
     // Generate basic component structure
     let instance: Component = {
       _id: Helpers.uuid(),
@@ -475,7 +487,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
         hover: {},
         active: {},
       },
-      _instanceName: `New ${definition.friendlyName || definition.name}`,
+      _instanceName: componentName,
       ...presetProps,
     }
 
@@ -500,7 +512,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
     }
 
     // Add step name to form steps
-    if (componentName.endsWith("/formstep")) {
+    if (componentType.endsWith("/formstep")) {
       const parentForm = findClosestMatchingComponent(
         screen.props,
         get(selectedComponent)?._id,
@@ -529,14 +541,14 @@ export class ComponentStore extends BudiStore<ComponentState> {
    * @returns
    */
   async create(
-    componentName: string,
+    componentType: string,
     presetProps: any,
     parent: Component,
     index: number
   ) {
     const state = get(this.store)
     const componentInstance = this.createInstance(
-      componentName,
+      componentType,
       presetProps,
       parent
     )
diff --git a/packages/builder/src/stores/builder/index.js b/packages/builder/src/stores/builder/index.js
index 54c1aa39a2..7dd7f67828 100644
--- a/packages/builder/src/stores/builder/index.js
+++ b/packages/builder/src/stores/builder/index.js
@@ -16,7 +16,7 @@ import { userStore, userSelectedResourceMap, isOnlyUser } from "./users.js"
 import { deploymentStore } from "./deployments.js"
 import { contextMenuStore } from "./contextMenu.js"
 import { snippets } from "./snippets"
-import { screenComponentErrors } from "./screenComponent"
+import { screenComponents, screenComponentErrors } from "./screenComponent"
 
 // Backend
 import { tables } from "./tables"
@@ -68,6 +68,7 @@ export {
   snippets,
   rowActions,
   appPublished,
+  screenComponents,
   screenComponentErrors,
 }
 
diff --git a/packages/builder/src/stores/builder/screenComponent.ts b/packages/builder/src/stores/builder/screenComponent.ts
index 47ac11a2c4..3338796283 100644
--- a/packages/builder/src/stores/builder/screenComponent.ts
+++ b/packages/builder/src/stores/builder/screenComponent.ts
@@ -2,21 +2,19 @@ import { derived } from "svelte/store"
 import { tables } from "./tables"
 import { selectedScreen } from "./screens"
 import { viewsV2 } from "./viewsV2"
-import {
-  findComponentsBySettingsType,
-  getManifestDefinition,
-} from "@/helpers/screen"
 import {
   UIDatasourceType,
   Screen,
   Component,
   UIComponentError,
+  ScreenProps,
 } from "@budibase/types"
 import { queries } from "./queries"
 import { views } from "./views"
 import { findAllComponents } from "@/helpers/components"
 import { bindings, featureFlag } from "@/helpers"
 import { getBindableProperties } from "@/dataBinding"
+import { componentStore, ComponentDefinition } from "./components"
 
 function reduceBy<TItem extends {}, TKey extends keyof TItem>(
   key: TKey,
@@ -47,13 +45,17 @@ const validationKeyByType: Record<UIDatasourceType, string | null> = {
 }
 
 export const screenComponentErrors = derived(
-  [selectedScreen, tables, views, viewsV2, queries],
-  ([$selectedScreen, $tables, $views, $viewsV2, $queries]): Record<
-    string,
-    UIComponentError[]
-  > => {
+  [selectedScreen, tables, views, viewsV2, queries, componentStore],
+  ([
+    $selectedScreen,
+    $tables,
+    $views,
+    $viewsV2,
+    $queries,
+    $componentStore,
+  ]): Record<string, UIComponentError[]> => {
     if (
-      !featureFlag.isEnabled("CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS") ||
+      !featureFlag.isEnabled("CHECK_COMPONENT_SETTINGS_ERRORS") ||
       !$selectedScreen
     ) {
       return {}
@@ -66,10 +68,12 @@ export const screenComponentErrors = derived(
       ...reduceBy("_id", $queries.list),
     }
 
+    const { components: definitions } = $componentStore
+
     const errors = {
-      ...getInvalidDatasources($selectedScreen, datasources),
-      ...getMissingAncestors($selectedScreen),
-      ...getMissingRequiredSettings($selectedScreen),
+      ...getInvalidDatasources($selectedScreen, datasources, definitions),
+      ...getMissingAncestors($selectedScreen, definitions),
+      ...getMissingRequiredSettings($selectedScreen, definitions),
     }
     return errors
   }
@@ -77,13 +81,15 @@ export const screenComponentErrors = derived(
 
 function getInvalidDatasources(
   screen: Screen,
-  datasources: Record<string, any>
+  datasources: Record<string, any>,
+  definitions: Record<string, ComponentDefinition>
 ) {
   const result: Record<string, UIComponentError[]> = {}
-  for (const { component, setting } of findComponentsBySettingsType(screen, [
-    "table",
-    "dataSource",
-  ])) {
+  for (const { component, setting } of findComponentsBySettingsType(
+    screen,
+    ["table", "dataSource"],
+    definitions
+  )) {
     const componentSettings = component[setting.key]
     if (!componentSettings) {
       continue
@@ -121,17 +127,20 @@ function getInvalidDatasources(
   return result
 }
 
-function getMissingRequiredSettings(screen: Screen) {
+function getMissingRequiredSettings(
+  screen: Screen,
+  definitions: Record<string, ComponentDefinition>
+) {
   const allComponents = findAllComponents(screen.props) as Component[]
 
   const result: Record<string, UIComponentError[]> = {}
   for (const component of allComponents) {
-    const definition = getManifestDefinition(component)
+    const definition = definitions[component._component]
     if (!("settings" in definition)) {
       continue
     }
 
-    const missingRequiredSettings = definition.settings.filter(
+    const missingRequiredSettings = definition.settings?.filter(
       (setting: any) => {
         let empty =
           component[setting.key] == null || component[setting.key] === ""
@@ -167,7 +176,7 @@ function getMissingRequiredSettings(screen: Screen) {
       }
     )
 
-    if (missingRequiredSettings.length) {
+    if (missingRequiredSettings?.length) {
       result[component._id!] = missingRequiredSettings.map((s: any) => ({
         key: s.key,
         message: `Add the <mark>${s.label}</mark> setting to start using your component`,
@@ -180,7 +189,10 @@ function getMissingRequiredSettings(screen: Screen) {
 }
 
 const BudibasePrefix = "@budibase/standard-components/"
-function getMissingAncestors(screen: Screen) {
+function getMissingAncestors(
+  screen: Screen,
+  definitions: Record<string, ComponentDefinition>
+) {
   const result: Record<string, UIComponentError[]> = {}
 
   function checkMissingAncestors(component: Component, ancestors: string[]) {
@@ -188,9 +200,9 @@ function getMissingAncestors(screen: Screen) {
       checkMissingAncestors(child, [...ancestors, component._component])
     }
 
-    const definition = getManifestDefinition(component)
+    const definition = definitions[component._component]
 
-    if (!("requiredAncestors" in definition)) {
+    if (!definition?.requiredAncestors?.length) {
       return
     }
 
@@ -204,7 +216,7 @@ function getMissingAncestors(screen: Screen) {
       }
 
       result[component._id!] = missingAncestors.map(ancestor => {
-        const ancestorDefinition: any = getManifestDefinition(ancestor)
+        const ancestorDefinition = definitions[`${BudibasePrefix}${ancestor}`]
         return {
           message: `${pluralise(definition.name)} need to be inside a
 <mark>${ancestorDefinition.name}</mark>`,
@@ -221,3 +233,52 @@ function getMissingAncestors(screen: Screen) {
   checkMissingAncestors(screen.props, [])
   return result
 }
+function findComponentsBySettingsType(
+  screen: Screen,
+  type: string | string[],
+  definitions: Record<string, ComponentDefinition>
+) {
+  const typesArray = Array.isArray(type) ? type : [type]
+
+  const result: {
+    component: Component
+    setting: {
+      type: string
+      key: string
+    }
+  }[] = []
+
+  function recurseFieldComponentsInChildren(component: ScreenProps) {
+    if (!component) {
+      return
+    }
+
+    const definition = definitions[component._component]
+
+    const setting = definition?.settings?.find((s: any) =>
+      typesArray.includes(s.type)
+    )
+    if (setting && "type" in setting) {
+      result.push({
+        component,
+        setting: { type: setting.type!, key: setting.key! },
+      })
+    }
+    component._children?.forEach(child => {
+      recurseFieldComponentsInChildren(child)
+    })
+  }
+
+  recurseFieldComponentsInChildren(screen?.props)
+  return result
+}
+
+export const screenComponents = derived(
+  [selectedScreen],
+  ([$selectedScreen]) => {
+    if (!$selectedScreen) {
+      return []
+    }
+    return findAllComponents($selectedScreen.props) as Component[]
+  }
+)
diff --git a/packages/types/src/sdk/featureFlag.ts b/packages/types/src/sdk/featureFlag.ts
index d9f092c80a..97893a1b5e 100644
--- a/packages/types/src/sdk/featureFlag.ts
+++ b/packages/types/src/sdk/featureFlag.ts
@@ -1,6 +1,6 @@
 export enum FeatureFlag {
   USE_ZOD_VALIDATOR = "USE_ZOD_VALIDATOR",
-  CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS = "CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS",
+  CHECK_COMPONENT_SETTINGS_ERRORS = "CHECK_COMPONENT_SETTINGS_ERRORS",
 
   // Account-portal
   DIRECT_LOGIN_TO_ACCOUNT_PORTAL = "DIRECT_LOGIN_TO_ACCOUNT_PORTAL",
@@ -8,7 +8,7 @@ export enum FeatureFlag {
 
 export const FeatureFlagDefaults = {
   [FeatureFlag.USE_ZOD_VALIDATOR]: false,
-  [FeatureFlag.CHECK_SCREEN_COMPONENT_SETTINGS_ERRORS]: false,
+  [FeatureFlag.CHECK_COMPONENT_SETTINGS_ERRORS]: false,
 
   // Account-portal
   [FeatureFlag.DIRECT_LOGIN_TO_ACCOUNT_PORTAL]: false,