diff --git a/bun.lockb b/bun.lockb
index 1172fa06..325149bc 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/package.json b/package.json
index 52d4a2d4..fb33fb52 100644
--- a/package.json
+++ b/package.json
@@ -94,6 +94,7 @@
"jose": "^5.9.3",
"jscad-electronics": "^0.0.24",
"jszip": "^3.10.1",
+ "kicad-converter": "^0.0.10",
"lucide-react": "^0.445.0",
"ms": "^2.1.3",
"next-themes": "^0.3.0",
diff --git a/src/components/DownloadButtonAndMenu.tsx b/src/components/DownloadButtonAndMenu.tsx
index 2a788e88..e025c14f 100644
--- a/src/components/DownloadButtonAndMenu.tsx
+++ b/src/components/DownloadButtonAndMenu.tsx
@@ -12,6 +12,7 @@ import { downloadFabricationFiles } from "@/lib/download-fns/download-fabricatio
import { downloadSchematicSvg } from "@/lib/download-fns/download-schematic-svg"
import { downloadReadableNetlist } from "@/lib/download-fns/download-readable-netlist"
import { downloadAssemblySvg } from "@/lib/download-fns/download-assembly-svg"
+import { downloadKicadFiles } from "@/lib/download-fns/download-kicad-files"
import { AnyCircuitElement } from "circuit-json"
import { ChevronDown, Download } from "lucide-react"
import React from "react"
@@ -107,14 +108,20 @@ export function DownloadButtonAndMenu({
notImplemented("kicad project download")}
+ onSelect={() => {
+ downloadKicadFiles(
+ circuitJson,
+ snippetUnscopedName || "kicad_project",
+ )
+ }}
>
Download KiCad Project
- kicad_*
+ kicad_*.zip
+
{
diff --git a/src/lib/download-fns/download-kicad-files.ts b/src/lib/download-fns/download-kicad-files.ts
new file mode 100644
index 00000000..44e9dfa2
--- /dev/null
+++ b/src/lib/download-fns/download-kicad-files.ts
@@ -0,0 +1,20 @@
+import { saveAs } from "file-saver"
+import { convertCircuitJsonToKiCadPcb } from "kicad-converter"
+import { AnyCircuitElement } from "circuit-json"
+import JSZip from "jszip"
+
+export const downloadKicadFiles = (
+ circuitJson: AnyCircuitElement[],
+ fileName: string,
+) => {
+ const kicadPcbString = convertCircuitJsonToKiCadPcb(circuitJson)
+ const pcbContent =
+ typeof kicadPcbString === "object"
+ ? JSON.stringify(kicadPcbString)
+ : kicadPcbString
+ const zip = new JSZip()
+ zip.file(`${fileName}.kicad_pcb`, pcbContent)
+ zip.generateAsync({ type: "blob" }).then((content) => {
+ saveAs(content, `${fileName}_kicad.zip`)
+ })
+}