TL;DR

The best tool for turning code into a PDF depends on why you need it. For a printable assignment or code review, use the VS Code Print extension — it keeps line numbers, syntax colors, and file paths in a single command. For a screenshot-style image you can paste into a slide deck, use Carbon.now.sh or Ray.so. For an entire folder of source files at once, use a batch tool like Convert: Anything to PDF. Everything else — pandoc, Puppeteer, custom scripts — is overkill unless you already know why you need it.

Method 1: VS Code Print extension

The most direct path from source code to a printable PDF is the Print extension by pdconsec (marketplace ID pdconsec.vscode-print). It uses the same PrismJS syntax highlighter the VS Code marketplace itself relies on, so the colors match your editor within a few shades. Install it, open a file, hit Ctrl+Alt+P (or Cmd+Alt+P on macOS), and it opens a print preview in your default browser. From there, "Save as PDF" produces a file that includes:

  • The full source with syntax highlighting
  • Line numbers in the left gutter
  • The file path in the header
  • Page numbers in the footer
  • A monospaced font (defaults to Consolas / Menlo)

When it's the right choice: printing homework assignments, submitting code as part of a job application, or attaching a code snapshot to a bug report. It handles single files and whole folders — right-click a folder in the Explorer and pick "Print" and it concatenates every file in the tree into one document.

Where it falls short: it renders through the browser, so print margins depend on Chrome or Firefox settings rather than the extension itself. On very long files (2,000+ lines), the browser print dialog can get slow. And because it's a print-preview flow, you get whatever your OS's Save-as-PDF driver produces, not a proper PDF/A archival file.

Configuration worth changing: print.fontSize (default 10pt is tight on paper — try 11pt), print.lineNumbers (set explicitly to on), print.colourScheme (pick a light theme for printer-friendly output), and print.editorTitleAsFilename (shows the tab title in the header).

For CodeHS or Repl.it code you can copy out but can't print directly, pasting into a new VS Code file and using Print is the fastest workaround.

Method 2: Carbon.now.sh

Carbon turns a code snippet into a stylized image — the "tweet screenshot" aesthetic you've seen on every dev blog since 2018. It exports to PNG or SVG, and you can then run those through a PDF converter. Carbon isn't really a code-to-PDF tool; it's a code-to-image tool that people repurpose.

Strengths:

  • Beautiful defaults. The dark themes (One Dark, Material, Night Owl) look better than any print extension's output.
  • Window chrome (macOS traffic lights, Windows title bar, or none) that makes screenshots look like editor windows.
  • Fine control over padding, drop shadow, background color, font family, and font size.
  • Line numbers optional; language detection automatic; over 100 supported languages.

Weaknesses:

  • Not designed for long files. Snippets over ~150 lines start to look absurd — a single tall image with no pagination.
  • No native PDF export. You export PNG, then use a converter or "Print to PDF" on the image.
  • The output is a rasterized picture, so you can't search or copy text from the PDF.
  • Free tier is completely free — no login, no watermark. There is no paid tier, which also means no support.

When it's the right choice: documentation, slide decks, tweets, blog headers, marketing pages, README hero images. Any place where the code is more decoration than reference material. Do not use it for legal filings, printed assignments, or anything that needs to be readable as text.

Workflow tip: if you need multiple snippets in one PDF, export them all as PNGs at the same width, then batch-merge them with a tool that stacks images vertically into a single document. Our guide on merging mixed file types into one PDF walks through exactly that flow.

Method 3: Ray.so

Ray.so is Raycast's take on the Carbon idea, and honestly it looks better out of the box. Same concept — paste code, pick a theme, export an image — but the defaults are more restrained and the themes hew closer to what modern editors actually look like (VS Code Dark+, GitHub Light, Solarized).

Key differences from Carbon:

  • Fixed background gradients rather than solid colors. Some people love this; some hate it.
  • PNG and SVG export only; no PDF. Same downstream conversion needed.
  • No window chrome options — always a rounded card, no macOS/Windows toggle.
  • Faster and lighter than Carbon. The whole page is a Next.js app with minimal state, so it renders instantly.
  • Copy-as-image button that puts the rendered snippet directly on your clipboard.

Where it beats Carbon: presentation slides. The gradient backgrounds look like they were designed by someone who cared, which Carbon's flat backgrounds do not. If you're building a Keynote or Google Slides deck about your codebase, Ray.so's output slots in without needing additional styling.

Where it loses to Carbon: anything you want to customize deeply. Ray.so is opinionated by design — you pick a theme and get what the theme gives you. Carbon lets you tweak everything.

Ray.so for printed output: don't. Same reason as Carbon — image-based, no pagination, no searchable text.

Method 4: Convert: Anything to PDF (batch)

If you need to convert a whole folder of source files — say, a homework submission with a dozen .py files, or a mini-project with .html, .css, and .js — the extension-by-extension approach breaks down. VS Code Print does folders, but you have to open the folder in VS Code first. Carbon and Ray.so are one-file-at-a-time.

Convert: Anything to PDF handles this from the browser. Drop a folder in, and every text-based file — including .py, .js, .ts, .rb, .go, .rs, .java, .cpp, .html, .css, .json, .yaml, .md, .sh — is rendered as a syntax-highlighted PDF page. Each file becomes its own section with a header showing the filename and language, and the output is a single merged PDF you can email, print, or upload to a course portal.

What matters here:

  • Everything runs locally. No files leave your machine, which matters when the code is proprietary or contains API keys. Web-based converters that require an upload are a bad fit for source code.
  • Line numbers on by default. You can turn them off if you're printing for aesthetic reasons rather than reference.
  • Language auto-detection based on file extension, with a manual override for files that lack one (like Dockerfile or Makefile).
  • Preserves folder structure in the table of contents, so a 40-file project reads like an ordered book instead of a random pile.

When to reach for it: submitting a coding assignment, archiving a codebase before a repo goes private, printing a code review for someone who wants paper, or bundling a project as a portfolio artifact.

For the general "everything into one PDF" version of this workflow — mixing code, docs, images, and spreadsheets — see the complete format guide.

Method 5: highlight.js + Puppeteer

For anyone who wants full control and doesn't mind writing code to convert code, the standard DIY stack is highlight.js for syntax coloring and Puppeteer for turning the resulting HTML into a PDF. This is the same stack most SaaS "code to PDF" services use under the hood.

A minimal Node script looks like this:

const fs = require('fs');
const hljs = require('highlight.js');
const puppeteer = require('puppeteer');

const code = fs.readFileSync('input.py', 'utf-8');
const highlighted = hljs.highlight(code, { language: 'python' }).value;

const html = `
  <!DOCTYPE html>
  <html>
    <head>
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js/styles/github.min.css">
      <style>
        pre { font-size: 11pt; line-height: 1.4; }
        body { font-family: 'JetBrains Mono', Menlo, monospace; margin: 40px; }
      </style>
    </head>
    <body><pre><code class="hljs">${highlighted}</code></pre></body>
  </html>
`;

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(html);
  await page.pdf({ path: 'output.pdf', format: 'A4', printBackground: true });
  await browser.close();
})();

When it's the right choice: you're building a service, adding "export to PDF" to your own product, or converting hundreds of files on a schedule. The upfront cost (setting up Node, installing Puppeteer's ~200MB Chromium download) only pays off if you're going to run it repeatedly.

Gotchas: Puppeteer downloads a full Chromium binary on install, which trips up corporate laptops with restricted egress. printBackground: true is required or you get white output with no colors — the syntax highlighting is applied via CSS backgrounds. And line numbers aren't built into highlight.js; you'll need a plugin like highlightjs-line-numbers.js or your own wrapping code.

If you're doing this at any real volume, our note on why local file conversion beats uploading to a web service applies doubly to code — you don't want proprietary source going through someone else's server.

Method 6: pandoc + LaTeX

The academic-paper approach. Pandoc can take source code (or Markdown files containing code blocks) and produce a LaTeX-styled PDF via xelatex or lualatex, using the listings or minted package for syntax highlighting.

A basic command:

pandoc input.py -o output.pdf \
  --pdf-engine=xelatex \
  --highlight-style=tango \
  -V geometry:margin=1in \
  -V fontsize=11pt \
  -V mainfont="DejaVu Sans Mono"

Strengths:

  • Typographically the nicest output of any option here. If you care about kerning, ligatures, and page breaks the way a book designer does, LaTeX is unbeatable.
  • Highly customizable — you can inject your own LaTeX template for corporate branding, add a table of contents, generate an index, or produce two-column output.
  • Works well as part of a larger document build system (a Makefile, a CI job, a thesis pipeline).

Weaknesses:

  • LaTeX is a heavy dependency. A full texlive-full install is 4–6 GB. basictex is smaller but often missing packages you need.
  • Error messages are famously opaque. Debugging why your PDF has a missing character can take an hour.
  • Overkill for one-off jobs. Nobody should install LaTeX just to print one Python file.

When it's the right choice: you're writing a thesis, a textbook, a technical report, or any document where the code is embedded in prose and both need to look professional. Also good when you already have LaTeX installed for other reasons.

For lighter Markdown-with-code needs — READMEs, documentation exports, developer notes — the Markdown to PDF comparison covers faster options that skip LaTeX entirely.

Comparison table

ToolBest forLine numbersBatchLocalCost
VS Code PrintHomework, printed codeYesFolder-levelYesFree
Carbon.now.shBlog posts, tweetsOptionalNoWeb-basedFree
Ray.soSlide decksOptionalNoWeb-basedFree
Convert: Anything to PDFMulti-file projects, archivesYesYesYesFree
highlight.js + PuppeteerCustom pipelinesWith pluginScriptableYesFree (dev time)
pandoc + LaTeXBooks, papers, thesesYesScriptableYesFree

If you already know which one fits your job, skip the rest of this post and use it. If you're between two of them, pick the one closer to "print a file right now" rather than the one closer to "set up a build system." You can always upgrade later.

Frequently asked questions

How do I save code as a PDF with syntax highlighting?

The fastest reliable path is the VS Code Print extension: install it, open your file, press Cmd+Alt+P (or Ctrl+Alt+P on Windows/Linux), and save the resulting print preview as a PDF. It preserves colors, line numbers, and the file path in the header. If you're not in VS Code, paste the code into Carbon.now.sh for a good-looking image, or use a batch tool like Convert: Anything to PDF if you need to process multiple files at once. All three work without uploading your source anywhere.

How do I save CodeHS code as a PDF?

CodeHS doesn't offer a native "export to PDF" button, so you need to copy the code out. The cleanest way: select all your code in the CodeHS editor, paste it into a new file in VS Code (naming it .py, .js, .java, or whichever language you're using), and print with the VS Code Print extension as described above. This gives you a proper syntax-highlighted PDF with line numbers, which is usually what teachers ask for. Alternatively, use a full-page screenshot extension to capture the CodeHS editor visually, but the code won't be searchable in the output.

How do I convert Python code to PDF?

Any of the six methods in this post works for Python — highlight.js, Prism (used by VS Code Print), Carbon, and pandoc all support Python out of the box. The choice depends on what the PDF is for. For a homework submission or code review, use the VS Code Print extension. For a slide or blog post, use Carbon or Ray.so. For an entire Python project with multiple .py files, use Convert: Anything to PDF or write a Puppeteer script. There's no Python-specific tool that's meaningfully better than these general-purpose options.

Which VS Code extension prints to PDF?

The most popular is Print by pdconsec (marketplace ID pdconsec.vscode-print). It has the most downloads, the most language support, and handles both single files and whole folders. Alternatives include PrintCode by nobuhito, which is simpler but hasn't been updated as recently, and Markdown PDF by yzane, which is Markdown-specific but handles code blocks inside Markdown files well. If you want a purely offline extension (no browser round-trip), vscode-pdf-generator exists but has a smaller feature set. Print is the default recommendation for 90% of use cases.

How do I convert an entire repository to PDF?

For a folder of files, three options in decreasing effort: (1) Open the folder in VS Code, right-click the root in the Explorer, pick "Print Folder" — Print concatenates every file into one document. (2) Use Convert: Anything to PDF to drop the whole folder in and get a merged PDF with a table of contents. (3) Write a shell script that loops through the files and runs pandoc or your Puppeteer script on each, then merges the results with pdfunite or pdftk. For most people, options 1 and 2 are enough. Option 3 makes sense only when you're doing this on a schedule or for very large codebases.

Bottom line

There isn't a single best tool for turning code into a PDF — there's a best tool for what you're actually trying to do. If you're printing homework or a code sample for a job interview, install the VS Code Print extension and stop overthinking it. If you're building a slide or a blog post, use Carbon or Ray.so and export as an image. If you're bundling a whole project, use Convert: Anything to PDF to turn the folder into a single searchable document without uploading anything. Everything else — pandoc, Puppeteer, custom scripts — is a real option only if you already know why you'd reach for it.