QSF Preview
A VS Code extension that renders Qualtrics Survey Format (.qsf) files as an interactive survey walkthrough.
What it does
Opens any .qsf file as a custom editor. Instead of raw JSON, you see:
- Survey outline (left): blocks → pages, jump to any page.
- Page view (right): all visible questions on the current page, rendered in a Qualtrics-style layout.
- Next / Back / Reset: walk the survey as a respondent would.
- Display logic: the most common Qualtrics conditions (
Selected, NotSelected, EqualTo, NotEqualTo, IsEmpty, IsNotEmpty) are evaluated live, so questions appear/disappear as you answer. Unsupported operators fail open with a warning banner.
Supported question types: MC (single/multi, vertical/horizontal), Matrix Likert (radio grid + dropdown), Text Entry (single/multi-line), Descriptive Block (HTML), Side-by-Side matrix, Pick-Group-Rank drag-and-drop. Timing questions are skipped (invisible).
Out of scope: randomization, quotas, branch/skip logic, embedded data, scoring, JS hooks (Qualtrics.SurveyEngine.addOnload).
Run from source
Install
Search for QSF Preview in the Extensions view, or run:
code --install-extension EndlessCG.qsf-preview
Run from source
cd qsf-preview
npm install
npm run build
Then from VS Code: open the qsf-preview/ folder and press F5 to launch an Extension Development Host. Open a .qsf file in that window.
To go back to the raw JSON view from inside a preview, use the command QSF: Open as JSON (Cmd/Ctrl-Shift-P).
Layout
qsf-preview/
src/ # extension host (Node)
extension.ts # entry, command registration
qsfPreview.ts # CustomEditorProvider + webview HTML/CSP
webview/ # webview bundle (browser)
main.ts # entry, postMessage handshake
model.ts # Survey/Block/Question/Answer types
parser.ts # QSF JSON → normalized model
logic.ts # DisplayLogic evaluator
runtime.ts # page state machine
render.ts # per-question-type renderers
styles.css
esbuild.mjs # bundles both targets to media/
media/ # build output (committed for "F5 and go")
smoke.mjs # parses ../template.qsf, walks every page (no DOM)
Architecture
The extension host reads file bytes and postMessages the parsed JSON to the webview. The webview runs in a sandboxed iframe with a strict CSP — no inline scripts, no remote resources. The webview owns the survey runtime (parser, logic engine, renderer); the host stays thin.
Author HTML inside questions is sanitized: <script> tags and on*= event-handler attributes are stripped. The strict CSP would block them anyway.