diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 3f432da..1251be8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -52,7 +52,7 @@ jobs:
           node-version: ${{ matrix.node }}
 
       - name: 📥 Download deps
-        run: ./scripts/install-dependencies ${{ matrix.svelte }}
+        run: npm run install:${{ matrix.svelte }}
 
       - name: ▶️ Run ${{ matrix.check }}
         run: npm run ${{ matrix.check }}
diff --git a/.gitignore b/.gitignore
index 151e826..ca3410b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ public/bundle.*
 coverage
 dist
 .idea
+*.tgz
 
 # These cause more harm than good when working with contributors
 yarn-error.log
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 92856ee..4c40705 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -58,6 +58,23 @@ npm test
 npm run test:watch
 ```
 
+### Using different versions of Svelte
+
+Use the provided script to set up your environment for different versions of Svelte:
+
+```shell
+# install Svelte 5
+npm run install:5
+
+# install Svelte 4
+npm run install:4
+
+# install Svelte 3
+npm run install:3
+```
+
+Not all checks will pass on `svelte<5`. Reference the CI workflows to see which checks are expected to pass on older versions.
+
 ### Docs
 
 Use the `toc` script to ensure the README's table of contents is up to date:
diff --git a/package.json b/package.json
index 0788f40..b65e953 100644
--- a/package.json
+++ b/package.json
@@ -75,7 +75,10 @@
     "build": "tsc -p tsconfig.build.json && cp src/component-types.d.ts types",
     "contributors:add": "all-contributors add",
     "contributors:generate": "all-contributors generate",
-    "preview-release": "./scripts/preview-release"
+    "preview-release": "./scripts/preview-release",
+    "install:3": "./scripts/install-dependencies 3",
+    "install:4": "./scripts/install-dependencies 4",
+    "install:5": "./scripts/install-dependencies 5"
   },
   "peerDependencies": {
     "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0",
diff --git a/src/__tests__/render.test-d.ts b/src/__tests__/render.test-d.ts
index 5b1e16a..08cad70 100644
--- a/src/__tests__/render.test-d.ts
+++ b/src/__tests__/render.test-d.ts
@@ -18,6 +18,14 @@ describe('types', () => {
     await rerender({ count: 0 })
   })
 
+  test('non-components are rejected', () => {
+    // eslint-disable-next-line @typescript-eslint/no-extraneous-class
+    class NotComponent {}
+
+    // @ts-expect-error: component should be a Svelte component
+    subject.render(NotComponent)
+  })
+
   test('invalid prop types are rejected', () => {
     // @ts-expect-error: name should be a string
     subject.render(Component, { name: 42 })
diff --git a/src/component-types.d.ts b/src/component-types.d.ts
index 2e4a5a5..9f707c2 100644
--- a/src/component-types.d.ts
+++ b/src/component-types.d.ts
@@ -1,17 +1,30 @@
 /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents */
-import type * as Svelte from 'svelte'
+import type {
+  Component as ModernComponent,
+  ComponentConstructorOptions as LegacyConstructorOptions,
+  ComponentProps,
+  EventDispatcher,
+  mount,
+  SvelteComponent as LegacyComponent,
+  SvelteComponentTyped as Svelte3LegacyComponent,
+} from 'svelte'
 
-type IS_MODERN_SVELTE = Svelte.Component extends (...args: any[]) => any
+type IS_MODERN_SVELTE = ModernComponent extends (...args: any[]) => any
   ? true
   : false
 
+type IS_LEGACY_SVELTE_4 =
+  EventDispatcher<any> extends (...args: any[]) => any ? true : false
+
 /** A compiled, imported Svelte component. */
 export type Component<
-  P extends Record<string, any>,
-  E extends Record<string, any>,
+  P extends Record<string, any> = any,
+  E extends Record<string, any> = any,
 > = IS_MODERN_SVELTE extends true
-  ? Svelte.Component<P, E> | Svelte.SvelteComponent<P>
-  : Svelte.SvelteComponent<P>
+  ? ModernComponent<P, E> | LegacyComponent<P>
+  : IS_LEGACY_SVELTE_4 extends true
+    ? LegacyComponent<P>
+    : Svelte3LegacyComponent<P>
 
 /**
  * The type of an imported, compiled Svelte component.
@@ -19,12 +32,12 @@ export type Component<
  * In Svelte 5, this distinction no longer matters.
  * In Svelte 4, this is the Svelte component class constructor.
  */
-export type ComponentType<C> = IS_MODERN_SVELTE extends true
-  ? C
-  : new (...args: any[]) => C
+export type ComponentType<C> = C extends LegacyComponent
+  ? new (...args: any[]) => C
+  : C
 
 /** The props of a component. */
-export type Props<C extends Component<any, any>> = Svelte.ComponentProps<C>
+export type Props<C extends Component> = ComponentProps<C>
 
 /**
  * The exported fields of a component.
@@ -32,9 +45,9 @@ export type Props<C extends Component<any, any>> = Svelte.ComponentProps<C>
  * In Svelte 5, this is the set of variables marked as `export`'d.
  * In Svelte 4, this is simply the instance of the component class.
  */
-export type Exports<C> = C extends Svelte.SvelteComponent
+export type Exports<C> = C extends LegacyComponent
   ? C
-  : C extends Svelte.Component<any, infer E>
+  : C extends ModernComponent<any, infer E>
     ? E
     : never
 
@@ -43,7 +56,6 @@ export type Exports<C> = C extends Svelte.SvelteComponent
  *
  * In Svelte 4, these are the options passed to the component constructor.
  */
-export type MountOptions<C extends Component<any, any>> =
-  IS_MODERN_SVELTE extends true
-    ? Parameters<typeof Svelte.mount<Props<C>, Exports<C>>>[1]
-    : Svelte.ComponentConstructorOptions<Props<C>>
+export type MountOptions<C extends Component> = C extends LegacyComponent
+  ? LegacyConstructorOptions<Props<C>>
+  : Parameters<typeof mount<Props<C>, Exports<C>>>[1]