← All projects
Build 06Accessible reading · Responsible Computing Club, SJSUShipped · Spring 2026

Luminara

Dense writing in. Clear writing out. Meaning kept.

An app that makes academic reading accessible. Upload a PDF, slides, a Word doc or even a photo of a page, and Luminara finds the hard parts, rewrites only those with a local AI model, and hands the file back in its original format. I led the backend.

My roleLead backend developer
AlsoHelped teammates with code & Figma
Team6 · Responsible Computing Club
AILocal llama3 via Ollama
StackFlask · spaCy · React · Docker
FIG. 01 · THE REAL APP● SCREENSHOT
Luminara upload screen with output format, language, page range and accessibility options
DYSLEXIA FRIENDLY · TEXT-TO-SPEECH · SIMPLIFYNOT STORED

Upload and choose. Pick an output format, a language and a page range, then turn on dyslexia-friendly mode, text-to-speech or simplification.

FIG. 02 · A REAL RUN● RECORDING
PDF IN → CONVERTED → DOWNLOADRUNNING LOCALLY

Convert and download. A real speech-outline PDF goes through the backend, comes back as clean text with its structure kept, and downloads as a file again.

01 · The problemWho it's for

It's not the student. It's the text.

Students struggle with academic reading not because they lack ability, but because the content isn't accessible. Three groups feel it the most.

01
Dense text

Long sentences and complex vocabulary overwhelm any reader.

02
ESL students

International learners face an extra language barrier on every page.

03
Dyslexic learners

Dense paragraphs make comprehension significantly harder.

Learning should be understandable for everyone, regardless of background, language or learning style.
02 · How it feelsTry it

Simplify the hard parts. Keep the rest.

Luminara doesn't rewrite the whole page. It flags only the difficult words and phrases, replaces those, and leaves everything else exactly where it was. Tap a highlighted word to save it to your dictionary.

FLAGGED WORDS · 6ILLUSTRATIVE TEXT
My dictionary
Tap any highlighted word to save it. Saved words are kept in mind the next time the model rewrites a page.

Learn, don't just simplify. Each entry has a part of speech and a clear definition, and the dictionary grows with the reader.

03 · The architectureIt started on a whiteboard

From a sketch to a seven-step pipeline.

This is the real sketch I drew for the backend. The idea that shaped everything is in step four: no full generation, only flags. The AI never gets to rewrite the whole document.

Hand-drawn Luminara backend pipeline sketch
ORIGINAL SKETCH · FEB 23, 2026
01
Upload

PDF, slides or Word doc, with an edge check on the file.

02
Extract text

Parse the file, save its type, convert to one common format.

03
Identify & flag

Find what's hard: for dyslexia, for language learners, or what the user asks.

04
Modify flags only

Keep the theme. No full generation. Output replacements for flagged spans.

05
Rebuild

Create the full text with the flags replaced.

06
Revert file type

Reverse step two, so the output matches the input format.

07
Output

Download, rasterize if needed, and delete the user's file.

04 · What I builtThe backend

The engine underneath the app.

I was the main backend developer: the Flask server and everything it does with a file. I also helped teammates write their code and design in Figma, so the whole team could ship together.

01 · FILES
Any format in, same format out

PDFs, slides, Word docs and photos of pages, with OCR for images, converted to text and back again.

PyMuPDF · pytesseract · python-pptx · python-docx · Pillow
02 · NLP
Find what's hard

Readability scoring and word-rarity checks flag difficult spans before any AI runs.

spaCy · textstat · wordfreq
03 · LOCAL AI
Rewrite only the flags

A local llama3 model replaces just the flagged spans, guided by the reader's saved words.

Ollama · llama3
04 · SECURITY
Accounts that hold up

JWT sign-in that blocks disposable emails, caps password length against malicious input, and rate-limits login attempts.

Flask · PyJWT
05 · API
Personal dictionary

Save, list and delete words with their part of speech and definition, tied to each user.

Flask · Flask-CORS
06 · SHIP
One-command setup

Frontend, backend and the AI model all start together with Docker Compose.

Docker · Docker Compose
05 · Listening to usersDemo feedback

Users told us it was too simple. So we changed the goal.

After the demo, people liked the idea but said the output lost important meaning, and they wanted help understanding hard words, not just removing them. We shifted from shortening text to helping people understand it.

WHAT WE HEARD
WORKEDSimplifying dense academic text
DIDN'TOutput got too simple and lost meaning
MISSINGHelp learning hard words, and better dyslexia support
→
WHAT WE CHANGED
MEANINGKeep the original meaning while simplifying
BALANCELess aggressive rewrites, so details stay
LEARNINGBuilt the personal dictionary
06 · Hard partsTested on real textbooks

Real textbooks, not sample data.

We tested with real textbooks from our own classes across several subjects, checking both readability and whether the meaning survived. Real text exposed problems sample data never would.

01 · SCORING
Unreliable readability scores

Flesch-Kincaid scores swung with text length, causing over- and under-flagging.

02 · FORMAT
Keeping the layout

Headers and titles had to stay in place while still being simplified when needed.

03 · INTEGRATION
Frontend ↔ backend

CORS and port issues between React and Flask, including the dictionary calls.

Responsible design

We limited how much we used AI. Cheaper, greener NLP does the flagging, and a local model does only the rewriting, so documents never have to leave the machine.

The team

Built together, shipped together.

I led the backend and treated Luminara like my own project, but it wouldn't exist without this team. Thank you for the support from the first sketch to the final demo.

Responsible Computing Club, SJSU · Spring 2026
Vishalkiran RaichurBACKEND LEAD
Shivaji Ganesh
Ryan Deng
Shubh Rawal
Naysa Ratra
Suhas Kappala
PythonFlaskPyJWTspaCytextstatwordfreqPyMuPDFpytesseractOllama · llama3ReactDocker Compose
↑↓ NAVIGATE↵ OPENESC CLOSE