The ideaSearch our PDFs, but it actually works
A lot of "add AI to our website" requests are really one request underneath: let people ask questions about our documents and get a straight answer. DocuSage is that, built as something you run yourself rather than something you rent.
You upload your manuals, policies or product sheets. DocuSage extracts the text, splits it into chunks, computes embeddings, and answers questions with retrieval-augmented generation — grounded in your documents rather than in whatever the model happens to remember. Then you drop the chatbot onto your site with a single script tag.
You run your own instance, on your own infrastructure, with your own API keys. Your documents and your customers' questions never pass through anyone else's service — there is no SaaS in the middle and no per-conversation pricing.
PipelineIngest once, answer grounded
Two paths run through the system. Ingestion happens once per document; the query path runs on every question and never touches the model until it has real chunks to work with.
IntegrationOne script tag, no cookies
The whole integration is a single tag. The project detail page generates it for you:
<script src="https://your-domain.com/embed.js"
data-token="<project-token>"
data-color="blue"
data-theme="light"
data-style="classic"
data-chatbot-name="DocuSage Assistant"
data-welcome-message="Hello, how can I help you?"
data-disclaimer-text="Answers are generated by AI and may not always be accurate."
></script>Three looks ship out of the box — classic, advanced and premium — switched with the data-style attribute. The widget sets no cookies and authenticates purely with the project token, so it works from any domain without a tracking script tagging along.
BuildBoring stack, on purpose
Nothing here is exotic. That is the point: a self-hosted product is only useful if the person deploying it can actually understand and operate it.
| Layer | Choice | Why |
|---|---|---|
| Frontend | React + TypeScript on Vite, Tailwind with ShadCN UI, Wouter for routing, TanStack Query for server state | Fast builds, typed end to end, and a component layer that is easy to restyle for whoever deploys it. |
| Backend | Node 20+ with Express, TypeScript ES modules | One language across the whole repo, and a runtime that runs anywhere without ceremony. |
| Database | PostgreSQL 14+ with Drizzle ORM, schema shared between client and server | Type-safe queries, one migration path, and the schema is a single source of truth rather than two drifting copies. |
| Auth | Passport local strategy, bcrypt password hashing, sessions in a Postgres store | Sessions survive a restart, and there is no third-party identity provider to sign up for before you can log in. |
| Documents | Multer upload, server-side PDF text extraction, chunking and embedding in a dedicated service layer | Ingestion is isolated behind its own module, so swapping the chunking strategy does not touch the API. |
| Hosting | Neon serverless driver for *.neon.tech, plain PostgreSQL connection for everything else | Detected from the connection string, so a managed database and a VPS both work with no config switch. |
ModelsNot tied to one vendor
The AI provider is chosen per project, not globally: OpenAI, Google Gemini or Azure OpenAI, each with its own model selection and API key. A team running one chatbot on Azure for compliance reasons and another on Gemini for cost reasons is a supported configuration, not a fork.
That mattered for a self-hosted tool more than it would for a SaaS. Whoever deploys DocuSage already has a vendor relationship, an approved-supplier list, or a region requirement — hardcoding one provider would rule out a large share of the people the project is for.
ScopeWhat's in the box
Multi-project, multi-tenant
Separate chatbots, documents, teams and API keys. Role-based access with hierarchical team permissions, so one instance serves more than one part of an organisation.
REST API
Documented public API with per-project tokens and call tracking, for when the embed widget is not the integration you want.
Analytics & the gap log
Usage analytics plus a log of the questions the chatbot could not answer — which doubles as a to-do list for your documentation.
Customisable without forking
Prompts live in one file, theming in CSS custom properties, and branding, language and colours are documented in their own customisation guide.
OpsThree documented deployment targets
Azure App Service, Google Cloud Run, and a plain VPS — all three written up in the README, with a production build verified to start from a clean install. Requirements are deliberately small: Node 20+, a PostgreSQL 14+ database, and one API key. SMTP is optional, and the README is explicit that without it account activation and password reset will not work.
The README has a section most side projects skip: if you deploy DocuSage for other people, you are the operator and the data controller. GDPR obligations, what gets sent to your chosen AI provider and where, keeping a visible AI disclaimer, and replacing the placeholder marketing copy — all spelled out before you go live, rather than discovered afterwards.
PracticeTreated like a real product
- CI on every push — build and test workflow, plus CodeQL scanning and a release workflow.
- Tests where they earn their keep — Vitest over auth, storage integration, PDF extraction and the failure-detection logic. Not coverage theatre; the four places where a regression would actually hurt.
- Dependabot configured, so a self-hosted deployment is not quietly rotting.
- SECURITY.md with the security model, recommended configuration and a disclosure route.
- Contribution path — CONTRIBUTING.md, issue templates and a PR template, because "open source" without a way in is just published source.
- Real documentation — a README that gets you running, plus separate architecture, API and customisation guides.
BoundariesWhat it deliberately isn't
The README says out loud who should not use this, which I think is the more honest half of a project page:
- PDF only. If you need to ingest other formats, this is not it yet.
- Not a hosted service. There is no instance to sign up for. Self-hosting is the product, not a fallback tier — nobody operates one for you, and that is the trade you are making in exchange for your data staying yours.
Both constraints keep the scope small enough that the thing actually works, ships and stays maintainable — which is worth more than a longer feature list.
Upload your PDFs, get a grounded chatbot on your site with one script tag — running on your own infrastructure, with your own keys.
Free and open source under MIT. Clone it, deploy it, change the prompts, ship it commercially — just keep the licence text.