diff --git a/docs/prql.md b/docs/prql.md
new file mode 100644
index 000000000..ad7663c19
--- /dev/null
+++ b/docs/prql.md
@@ -0,0 +1,50 @@
+---
+index: true
+sql:
+ gaia: ./lib/gaia-sample.parquet
+---
+
+# PRQL
+
+[PRQL](https://prql-lang.org/) (pronounced “prequel”) is a “modern language for transforming data — a simple, powerful, pipelined SQL replacement.” To use PRQL instead of SQL, create a PRQL fenced code block (```prql
). For example:
+
+````md
+```prql
+from gaia
+sort {phot_g_mean_mag}
+take 10
+```
+````
+
+This produces:
+
+```prql
+from gaia
+sort {phot_g_mean_mag}
+take 10
+```
+
+Because PRQL is compiled to SQL during build, Framework does not support a `prql` tagged template literal; PRQL can only be used in PRQL code blocks.
+
+## prql-js
+
+You can load `prql-js` as:
+
+````md run=false
+
+
+````
+
+```js echo
+const {compile} = wasm_bindgen;
+await wasm_bindgen(import.meta.resolve("npm:prql-js/dist/web/prql_js_bg.wasm"));
+```
+
+Then to use it:
+
+```js echo
+compile("from employees\nfilter salary > $1\nselect first_name")
+```
+
+
+
diff --git a/package.json b/package.json
index ab6560fc0..f6ed46349 100644
--- a/package.json
+++ b/package.json
@@ -77,6 +77,7 @@
"mime": "^4.0.0",
"minisearch": "^6.3.0",
"open": "^10.1.0",
+ "prql-js": "^0.11.3",
"rollup": "^4.6.0",
"rollup-plugin-esbuild": "^6.1.0",
"semver": "^7.5.4",
diff --git a/src/markdown.ts b/src/markdown.ts
index 6e887a7c5..31db435f6 100644
--- a/src/markdown.ts
+++ b/src/markdown.ts
@@ -14,6 +14,7 @@ import {parseInfo} from "./info.js";
import type {JavaScriptNode} from "./javascript/parse.js";
import {parseJavaScript} from "./javascript/parse.js";
import {relativePath} from "./path.js";
+import {transpilePrql} from "./prql.js";
import {transpileSql} from "./sql.js";
import {transpileTag} from "./tag.js";
import {InvalidThemeError} from "./theme.js";
@@ -60,6 +61,8 @@ function getLiveSource(content: string, tag: string, attributes: Record): string {
+ try {
+ content = prql2sql(content, prqlOptions) ?? "";
+ } catch (error: any) {
+ const [message] = JSON.parse(error.message).inner;
+ throw new SyntaxError(message.display);
+ }
+ return transpileSql(content, attributes);
+}
diff --git a/yarn.lock b/yarn.lock
index 45b8690fb..92af30826 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2965,6 +2965,11 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+prql-js@^0.11.3:
+ version "0.11.3"
+ resolved "https://registry.yarnpkg.com/prql-js/-/prql-js-0.11.3.tgz#17e6799144874003135a2d207d61368f3c07b719"
+ integrity sha512-Od8Glg/m2KaaQyeu9/xpZvHi/tUW5S6sp3pozDzhht+R6+JqAfLW0VUDT30nfNBQ9guuEABs1t5w+0CemUJC6A==
+
psl@^1.1.33:
version "1.9.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"