npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cas-pdf-parser-react

v0.1.3

Published

React hooks and components for cas-pdf-parser — parse Indian CAS PDFs in the browser

Readme

cas-pdf-parser-react

React hook and drop-in component for parsing Indian CAS PDFs in the browser.

Built on top of cas-pdf-parser. Supports CAMS, KFintech, NSDL, and CDSL statements.

npm install cas-pdf-parser-react cas-pdf-parser

Components

<CASFileInput /> — drop-in UI

Zero-config file input with drag-and-drop, password field, and parse button.

import { CASFileInput } from 'cas-pdf-parser-react';
import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url'; // Vite

function App() {
  return (
    <CASFileInput
      workerSrc={workerSrc}
      onParsed={(data) => console.log(data)}
      onError={(msg) => console.error(msg)}
    />
  );
}

Props

| Prop | Type | Default | Description | |---|---|---|---| | workerSrc | string | required | Path to pdfjs worker script | | maxFileSizeMB | number | 10 | Max file size before rejecting | | onParsed | (data: ParseResult) => void | — | Called with parsed data on success | | onError | (error: string) => void | — | Called with error message on failure | | className | string | — | Class applied to the outer wrapper div | | passwordPlaceholder | string | 'PAN / Password' | Placeholder for password field |

The component manages all state internally. Style it via className or the data-cas-status attribute:

[data-cas-status="parsing"] { opacity: 0.7; }
[data-cas-status="done"]    { border-color: green; }
[data-cas-status="error"]   { border-color: red; }

useCASParser — hook

Full control over the parse lifecycle.

import { useCASParser } from 'cas-pdf-parser-react';
import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url';

function MyUploader() {
  const { parse, data, status, error, reset } = useCASParser({
    workerSrc,
    maxFileSizeMB: 10,
    onSuccess: (data) => console.log('Parsed:', data),
    onError:   (msg)  => console.error('Error:', msg),
  });

  const handleFile = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) await parse(file, 'ABCDE1234F');
  };

  return (
    <div>
      <input type="file" accept=".pdf" onChange={handleFile} />
      <p>Status: {status}</p>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      {data  && <pre>{JSON.stringify(data, null, 2)}</pre>}
      {status === 'done' && <button onClick={reset}>Reset</button>}
    </div>
  );
}

Options

| Option | Type | Default | Description | |---|---|---|---| | workerSrc | string | required | Path to pdfjs worker script | | maxFileSizeMB | number | 10 | Max file size, rejected before parsing | | onSuccess | (data: ParseResult) => void | — | Called on successful parse | | onError | (error: string) => void | — | Called on failure |

Return values

| Value | Type | Description | |---|---|---| | parse | (file: File, password: string) => Promise<void> | Trigger a parse | | data | ParseResult \| null | Parsed result, null until done | | status | ParseStatus | Current state (see below) | | error | string \| null | Error message, non-null only on error | | reset | () => void | Reset back to idle |

Status values

| Status | Meaning | |---|---| | idle | Waiting for input | | validating | Checking file size and type | | parsing | PDF is being parsed | | done | Parse succeeded, data is available | | error | Parse failed, error has the message |


Setting up the pdfjs worker

The worker script must be served from your public folder. Pick the method for your bundler:

Vite

import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url';

Next.js (App Router)

Copy the worker to your public folder:

cp node_modules/pdfjs-dist/build/pdf.worker.min.mjs public/

Then pass:

workerSrc="/pdf.worker.min.mjs"

Create React App / Webpack

import { workerSrc } from 'pdfjs-dist/build/pdf.worker.entry';

Full Example — CASFileInput with data display

import { useState } from 'react';
import { CASFileInput, type ParseResult } from 'cas-pdf-parser-react';
import workerSrc from 'pdfjs-dist/build/pdf.worker.min.mjs?url';

export default function PortfolioPage() {
  const [portfolio, setPortfolio] = useState<ParseResult | null>(null);

  return (
    <div style={{ maxWidth: 520, margin: '0 auto', padding: 24 }}>
      <CASFileInput
        workerSrc={workerSrc}
        onParsed={setPortfolio}
        onError={(msg) => alert(msg)}
      />

      {portfolio && (
        <div style={{ marginTop: 24 }}>
          <h2>{portfolio.investor_info.name}</h2>
          <p>File type: {portfolio.file_type}</p>

          {'folios' in portfolio && (
            <ul>
              {portfolio.folios.map((folio) =>
                folio.schemes.map((scheme) => (
                  <li key={scheme.isin ?? scheme.scheme}>
                    {scheme.scheme} —{' '}
                    {scheme.valuation.value.toFixed(2)}
                  </li>
                ))
              )}
            </ul>
          )}
        </div>
      )}
    </div>
  );
}

ParseResult shape

ParseResult is CASData | NSDLCASData. Distinguish them with:

if ('folios' in data) {
  // CASData — CAMS or KFintech
  data.folios[0].schemes[0].transactions
} else {
  // NSDLCASData — NSDL or CDSL
  data.accounts[0].equities
  data.accounts[0].mutual_funds
  data.nps?.schemes
}

See cas-pdf-parser for the full response shape.


Peer Dependencies

| Package | Version | |---|---| | react | >=17 | | cas-pdf-parser | * | | pdfjs-dist | bundled inside cas-pdf-parser |


License

MIT