diff --git a/.changeset/eleven-guests-rhyme.md b/.changeset/eleven-guests-rhyme.md
new file mode 100644
index 000000000..183f73829
--- /dev/null
+++ b/.changeset/eleven-guests-rhyme.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Updates `
` component to cache and reuse Shiki highlighters
diff --git a/packages/astro/components/Code.astro b/packages/astro/components/Code.astro
index 32c441495..e829f87be 100644
--- a/packages/astro/components/Code.astro
+++ b/packages/astro/components/Code.astro
@@ -1,6 +1,6 @@
---
import type * as shiki from 'shiki';
-import { getHighlighter } from 'shiki';
+import { getHighlighter } from './Shiki.js';
export interface Props {
/** The code to highlight. Required. */
diff --git a/packages/astro/components/Shiki.js b/packages/astro/components/Shiki.js
new file mode 100644
index 000000000..9e8e60bc2
--- /dev/null
+++ b/packages/astro/components/Shiki.js
@@ -0,0 +1,22 @@
+import { getHighlighter as getShikiHighlighter } from 'shiki';
+
+// Caches Promise for reuse when the same theme and langs are provided
+const _resolvedHighlighters = new Map();
+
+function stringify(opts) {
+ // Always sort keys before stringifying to make sure objects match regardless of parameter ordering
+ return JSON.stringify(opts, Object.keys(opts).sort());
+}
+
+export function getHighlighter(opts) {
+ const key = stringify(opts);
+
+ // Highlighter has already been requested, reuse the same instance
+ if (_resolvedHighlighters.has(key)) { return _resolvedHighlighters.get(key) }
+
+ // Start the async getHighlighter call and cache the Promise
+ const highlighter = getShikiHighlighter(opts);
+ _resolvedHighlighters.set(key, highlighter);
+
+ return highlighter;
+}
\ No newline at end of file