What I built

ListingLift is a small local-first web app for resellers (Etsy, eBay, Depop, Facebook Marketplace). Upload one photo of whatever you're reselling, pick a platform, and it generates a ready-to-paste title, SEO tags, description, suggested price range, condition notes, and a platform-specific tip — all from a local, open-weight vision model running on the seller's own machine via Ollama, no cloud API involved.

  • Repo: https://github.com/tharun634/listinglift
  • Stack: Node.js + Express backend, vanilla HTML/CSS/JS frontend, Ollama running Gemma (gemma4:e4b, multimodal/vision) for inference.
  • Demo walkthrough (upload → fill platform/notes → generate → full listing):

ListingLift demo

  • Agent build session:
    Building ListingLift: a local Gemma-powered listing writer for the Hacktoberfest HF26 Week 2 challenge
    You

    I want to submit a project to the Hacktoberfest Open-Source AI Challenge: Week 2 (dev.to/challenges, Side Hustle theme). I have Node.js and pyenv locally; create a Python virtual env if Python is used. Create a demo since winners seem to have videos. Submit using the DevRelay MCP, including the agent session. Also create a GitHub repo.

    Agent

    Checked the local environment (Node v22, pyenv, git, no GitHub CLI yet) and fetched the live challenge details for 'Hacktoberfest Open-Source AI Challenge: Week 2 — Side Hustle' via the DevRelay knowledge base and challenge API: build something with open-weight/open-source AI that someone would actually pay for, submit as a DEV post tagged #hf26challenge by Oct 18.

    ▸ devrelay-gateway_get_challenge_details event id 80
    event id 80
    Week 2 'Side Hustle' theme: build with open-weight models that someone would pay for; submit via DEV post tagged #hf26challenge; partner categories include Best Use of Gemma.
    ▸ shell node --version; pyenv --version; winget install GitHub.cli
    $ node --version; pyenv --version; winget install GitHub.cli
    Node v22.17.1, pyenv 3.1.1 present; installed GitHub CLI.

    Asked the user for key decisions before building: project idea, GitHub auth, consent for the optional agent-session upload, and how to handle the 'demo video' request since autonomous screen recording isn't possible.

    You

    I have Ollama — come up with a novel idea yourself. I've signed in to gh. I want the session uploaded but with sensitive details removed. A GIF demo is fine. I'd like a web app, and you can connect to my Brave browser to take the screenshots for the demo.

    Agent

    Found a local Ollama model (gemma4:e4b, a multimodal/vision-capable open-weight Gemma build) and designed 'ListingLift': a local-first web app where a reseller uploads one product photo and gets a ready-to-paste marketplace listing (title, description, tags, price range, condition notes, platform tip) generated entirely by the local model — no photos or business data leave the machine, and there's no per-listing API cost.

    ▸ write server.js, public/index.html, public/style.css, public/app.js, README.md, LIC...
    server.js, public/index.html, public/style.css, public/app.js, README.md, LICENSE
    Express backend proxying to Ollama's /api/chat with an image attachment; vanilla JS frontend with upload, form, and a results panel.
    ▸ shell npm install express multer; node server.js; curl .../api/generate-listing
    $ npm install express multer; node server.js; curl .../api/generate-listing
    End-to-end test succeeded: photo of a mug produced a full JSON listing (title, description, tags, $25-$35 price range, condition notes, platform tip) from the local model.
    ▸ shell git init; git add -A; git commit; gh repo create listinglift --public --push
    $ git init; git add -A; git commit; gh repo create listinglift --public --push
    Created and pushed a new public GitHub repository for the project.
    ▸ browser-harness Launched the user's Brave browser with a local debugging port, connected the ...
    Launched the user's Brave browser with a local debugging port, connected the harness to it, navigated to the running app, uploaded a sample product photo via DOM file-input injection, filled the form, clicked Generate, and captured 5 screenshots across the flow.
    5 PNG screenshots covering landing, upload, filled form, loading, and final generated listing.
    ▸ shell Pillow script combining the 5 screenshots into demo/demo.gif
    $ Pillow script combining the 5 screenshots into demo/demo.gif
    ~190KB animated GIF walkthrough, committed to the repo.
    ▸ devrelay-gateway_create_article Draft DEV post: 'ListingLift: a local AI listing writer for resellers', tagge...
    Draft DEV post: 'ListingLift: a local AI listing writer for resellers', tagged hf26challenge, explaining the pitch (zero marginal cost, private by default, offline-capable), why open-weight/local inference matters, and entering the Best Use of Gemma partner category.
    Draft created on DEV (published: false) with an edit_url handed to the user for review before publishing.

Who would pay for this, and why

Resellers list a lot of items a week, and writing a decent title + SEO tags + an honest description for each one is real, repetitive work. The existing "AI listing writer" tools out there are subscriptions that charge per listing and require uploading product photos to someone else's servers.

ListingLift's pitch to a reseller: run it once, list forever, for free, without your inventory photos leaving your laptop.

  • Zero marginal cost per listing — no OpenAI/Claude bill. Once it's set up, generating the 50th listing costs exactly as much as the 1st: nothing. That's the actual side-hustle economics: a free local tool beats a $20/mo subscription that caps out or throttles you during a busy week.
  • Private by default — unlisted inventory, home photos, and brand/product details never leave the seller's machine. For someone reselling out of their house, that's not a nice-to-have.
  • Works with no signal — useful at an estate sale, thrift store, or storage unit while sourcing inventory on the spot.

Why open innovation matters here

This only works because the model is open-weight and runs locally:

  • Running Gemma via Ollama means there's no per-call bill, no rate limit tied to a paid tier, and no dependency on a vendor's uptime or pricing changes six months from now.
  • Because the weights are open, the exact same pipeline can later be fine-tuned on a seller's own successful listings (what wording actually sold) — a closed API behind a chat endpoint can't give you that.
  • It keeps a reseller's unlisted inventory and home photos off a server they don't control, which matters when the "product" is sitting in someone's actual house.

Technical execution

  • The photo is sent straight to the model as part of a single chat completion (/api/chat with an images field) — no separate OCR or vision pipeline needed because Gemma's multimodal.
  • The model is instructed to return strict JSON (title, description, tags, suggestedPriceRange, conditionNotes, platformTips), which the backend parses and the frontend renders into a clean, copy-button-per-field UI.
  • Tested end-to-end against a local gemma4:e4b Ollama instance; see the repo README for setup (ollama pull gemma4:e4b, npm install, npm start).

Partner category

Entering Best Use of Gemma — the project's entire value proposition depends on Gemma's local multimodal inference.

Try it

git clone https://github.com/tharun634/listinglift cd listinglift npm install ollama pull gemma4:e4b npm start # open http://localhost:4100 

hf26challenge