
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@privyid/ghoulscript
Advanced tools
Compress, merge, split, and render pages to image using Ghostscript
yarn add @privyid/ghoulscript
import { optimizePDF } from '@privyid/ghoulscript'
const input = document.querySelector('input[type="file"]')
input.addEventListener('change', async () => {
if (input.files) {
const file = input.files[0]
const output = await optimizePDF(file)
const outputURL = URL.createObjectURL(new Blob([output], { type: 'application/pdf' }))
window.open(outputURL, '_blank')
}
})
import fs from 'node:fs/promises'
import { resolve } from 'node:path'
import { optimizePDF } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const output = await optimizePDF(buffer)
await fs.writeFile(resolve(__dirname, './sample.compressed.pdf'), output)
Compress and optimize PDF for Web Viewer.
import { optimizePDF } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const output = await optimizePDF(buffer, { password: '******' })
await fs.writeFile(resolve(__dirname, './sample.compressed.pdf'), output)
| Options | Type | Default | Description |
|---|---|---|---|
password | String | - | Document protection password |
pdfSettings | String | screen | Preset setting, valid value is screen, ebook, printer, prepress, default |
fastWebView | Boolean | true | Enable Fast Web View (Linearization) |
compatibilityLevel | String | 1.4 | Compability version |
colorConversionStrategy | String | RGB | Color conversion strategy, valid value is RGB, CMYK |
noTransparency | Boolean | true | Remove transparency |
keepPassword | Boolean | true | Keep document password if document have a password protection |
userPassword | String | - | Set User Password to document |
ownerPassword | String | - | Set Owner Password to document |
colorImageResolution | Number | 300 | Color image resolution |
grayImageResolution | Number | 300 | Gray image resolution |
monoImageResolution | Number | 300 | Mono image resolution |
args | String[] | - | Additional arguments |
Combine multiple PDF files into single PDF
import { combinePDF } from '@privyid/ghoulscript'
const bufferA = await fs.readFile(resolve(__dirname, './sample-1.pdf'))
const bufferB = await fs.readFile(resolve(__dirname, './sample-2.pdf'))
const output = await combinePDF([bufferA, bufferB])
await fs.writeFile(resolve(__dirname, './sample.combine.pdf'), output)
Split single PDF into multiple files
import { splitPdf } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const outputs = await splitPdf(buffer, ['1-5', '5-12'])
await fs.writeFile(resolve(__dirname, './sample.part1.pdf'), outputs[0])
await fs.writeFile(resolve(__dirname, './sample.part2.pdf'), outputs[1])
Set new User Password and Owner Password
import { addPassword } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const output = await addPassword(buffer, '123456', '112233')
await fs.writeFile(resolve(__dirname, './sample.protected.pdf'), output)
It's equal to compressPDF's userPassword and ownerPassword options
Remove existing encrypted PDF
import { removePassword } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.protected.pdf'))
const output = await removePassword(buffer, '123456')
await fs.writeFile(resolve(__dirname, './sample.unprotected.pdf'), output)
It's equal to compressPDF's keepPassword: false
Convert specific page to image
import { renderPageAsImage } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const output = await renderPageAsImage(buffer, 5, { format: 'jpg' })
await fs.writeFile(resolve(__dirname, './sample.jpg'), output)
| Options | Type | Default | Description |
|---|---|---|---|
resolution | Number | 96 | Render resolution |
textAlphaBits | Number | 4 | Text alpha bits, valid value is 1-4 |
graphicsAlphaBits | Number | 4 | Graphic alpha bits, valid value is 1-4 |
format | String | jpg | Render format, valid value is jpg or png |
args | String[] | - | Additional arguments |
Extract pages info
import { getInfo } from '@privyid/ghoulscript'
const buffer = await fs.readFile(resolve(__dirname, './sample.pdf'))
const info = await getInfo(buffer)
console.log(info)
/*
{
numPages: 5,
pages: [
{
page: 1,
width: 612,
height: 792,
},
{
page: 2,
width: 612,
height: 792,
},
{
page: 3,
width: 612,
height: 792,
},
]
}
*/
Check document is require password or not to open.
import { isRequirePassword } from '@privyid/ghoulscript'
const bufferA = await fs.readFile(resolve(__dirname, './sample.pdf'))
const bufferB = await fs.readFile(resolve(__dirname, './sample.protected.pdf'))
console.log(await isRequirePassword(bufferA)) // false
console.log(await isRequirePassword(bufferB)) // true
FAQs
Unknown package
We found that @privyid/ghoulscript demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.