DEV Community

Yuvraj Singh
Yuvraj Singh

Posted on

Qwen3, Local AI: Meet Elsewhere That Doesn't Want Your Attention🌿

Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass Submission 🌿

Elsewhere — Don't Remind Me. Give Me a Reason.

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass.

Elsewhere app screenshot

🚀 Try It and Explore the Code

The web app is deployed on Render. Although the Hugging Face Space and local inference integrations have been tested separately, the active AI provider in the public deployment has not yet been verified.

Less time deciding what to do. More time actually doing it.

🌱 The Idea

We don't need another app telling us to go outside. Most of us already know we should.

The harder part is deciding what to do with the free time we have.

You're sitting at your laptop, scrolling on your phone, and a simple question comes up:

Okay, what should I actually do?

I built Elsewhere around a different idea:

Don't just remind people to go outside. Give them a reason to.

Imagine you're into photography, have 30 minutes free, and a friend happens to be nearby. Instead of throwing fifty activities at you, Elsewhere uses that context to suggest one small, actionable outdoor quest.

The AI isn't the destination. The outside world is.

⚡ How It Works

flowchart TD
    A["Your interests"] --> D["Elsewhere"]
    B["Time available"] --> D
    C["Nearby friend context"] --> D
    D --> E["Generate one outdoor quest"]
    E --> F["Close the app"]
    F --> G["Go do something"]
    style D fill:#d9f99d,stroke:#3f6212,color:#1a2e05
    style G fill:#bbf7d0,stroke:#166534,color:#14532d

Three inputs. One suggestion. No endless feed.

For example:

Your friend is nearby, and you both have 20 minutes. Meet up and explore somewhere you wouldn't normally go.

The intended experience is simple:

  1. Open Elsewhere.
  2. Get a reason.
  3. Close the app.
  4. Go outside.

🛠️ The Technical Architecture

Elsewhere is a Progressive Web App (PWA) backed by Node.js and Express. Its suggestion pipeline supports hosted Hugging Face inference, optional local inference through llama.cpp, and a deterministic fallback.

flowchart TD
    U["Browser / PWA"] --> API["Node.js + Express"]
    API --> CTX["Build suggestion prompt<br/>Interests · Duration · Friend context"]
    CTX --> HF{"Hugging Face<br/>Space configured?"}
    HF -->|Yes| HFI["Qwen3 1.7B<br/>ZeroGPU inference"]
    HFI -->|Usable response| OUT["Clean suggestion"]
    HFI -->|Failure / no usable text| LOCAL{"Local LLM configured?"}
    HF -->|No| LOCAL
    LOCAL -->|Yes| LLAMA["llama.cpp<br/>OpenAI-compatible API"]
    LLAMA -->|Usable response| OUT
    LLAMA -->|Failure / no usable text| FALLBACK["Deterministic fallback"]
    LOCAL -->|No| FALLBACK
    OUT --> RESP["Return suggestion"]
    FALLBACK --> RESP
    RESP --> U

The diagram describes the backend's intended provider-selection and fallback logic. It does not establish that every path works in the deployed Render environment.

The stack

Layer Technology Purpose
Frontend HTML, CSS, JavaScript, PWA User experience
Backend Node.js, Express API and suggestion orchestration
Hosted AI Hugging Face Space Qwen3 inference
Local AI llama.cpp Local OpenAI-compatible inference
Model Qwen3 1.7B Generates short outdoor suggestions
Deployment Render Hosts the web app and backend

🧠 Following a Suggestion Through the System

Here's the request lifecycle in a little more detail.

sequenceDiagram
    participant U as User
    participant W as Web App
    participant S as Express Server
    participant H as Hugging Face
    participant L as Local llama.cpp

    U->>W: Select interests and available time
    W->>S: POST /api/suggestion
    S->>S: Build contextual prompt
    alt Hugging Face configured
        S->>H: Request Qwen3 suggestion
        H-->>S: Inference result
    else Hosted provider unavailable or unusable
        S->>L: Try local inference if configured
        L-->>S: Model response or failure
    end
    S->>S: Clean result or use fallback
    S-->>W: Return suggestion
    W-->>U: Display one outdoor quest

The server owns provider selection and response handling. The browser doesn't need to know which model generated the suggestion.

That separation also makes it possible to test inference independently of the public deployment.

🔬 What I Actually Tested

I wanted to distinguish a working integration from an architecture that merely looks good on paper.

Test Result
Local llama.cpp health endpoint Passed
Local app → llama.cpp suggestion request Passed during testing
Local app → Hugging Face Space inference Successful response observed
Hugging Face Space direct demo Tested successfully
Full browser and geolocation flow Not fully verified
AI inference through the public Render deployment Not verified

One successful hosted-inference test returned:

Find a quiet spot to do calisthenics and enjoy the breeze.

The local integration also returned a model-generated response through the app's suggestion endpoint.

These checks confirmed that both inference paths could produce responses during their respective tests. They don't prove continuous availability or successful inference on every request.

🔌 Why Open-Weight AI?

I wanted to explore what a small, focused application could do with open-weight AI without making every interaction dependent on a closed, hosted API.

Using Qwen3 with a Hugging Face Space gives the project a hosted inference path. Supporting llama.cpp also gives me a way to run inference locally through an OpenAI-compatible API.

The trade-offs are different:

  • Hosted inference: Easier to access without running a model on your own machine, but dependent on service availability and usage limits.
  • Local inference: More control over where the model runs, but requires a compatible server and sufficient local resources.
  • Deterministic fallback: Keeps the suggestion flow useful when a model isn't configured or returns no usable response.
flowchart LR
    A["Suggestion request"] --> B{"Inference available?"}
    B -->|Hosted| C["Hugging Face + Qwen3"]
    B -->|Local| D["llama.cpp + Qwen3"]
    B -->|Neither| E["Fallback template"]
    C --> F["One suggestion"]
    D --> F
    E --> F

For this project, AI is a means to an end. It should make the suggestion more relevant, not turn a five-minute decision into a twenty-minute conversation.

🔒 Privacy and Product Decisions

Elsewhere is deliberately designed to resist becoming another attention-consuming product.

  • No endless feeds.
  • No streaks or gamification loops.
  • No notification loops.
  • No endless AI conversations.
  • Nearby-friend context is intended to help people make plans, not encourage constant checking.

The current backend uses in-memory state for group and presence data, rounds location information, and expires presence after a limited period. The exact privacy properties still depend on the implemented flows and deployment configuration.

The guiding principle is simple: help people spend less time on the screen, not more.

🧪 My Agent Session

I used DevRelay to document the repository architecture, trace the suggestion-generation flow, and test the local LLM integration.

The session separates source-code findings from results verified through live local checks, while identifying behavior that remains untested.

Tracing Elsewhere's Local LLM Suggestion Flow
You

Inspect my existing Elsewhere project read-only. Trace suggestion generation, the local LLM integration and fallback, check local model status, and if practical perform a harmless suggestion-endpoint test. Do not read .env, reveal secrets, modify project files, or publish. Separate source-verified findings, live test results, and unverified behavior. Show the detailed findings and proposed transcript before saving.

Agent

Verified from source: the documented local web run steps are cd web, npm install, cp .env.example .env, npm run dev. The local LLM README expects llama.cpp at localhost:8080/v1 and does not supply one specific launch command. Verified live: llama.cpp health was OK, two model entries were listed, and the app returned a model-generated suggestion with llmConfigured=true and no LLM error. Not tested: full documented install/run flow, real browser/geolocation/circle flow, and the public Render deployment. Render AI configuration was not inspected, so no claim is made about its provider. The actual .env, credentials, and private paths were not read or included. No project files were changed.

🏆 Prize Categories

  • Render — Best Use of Render: Hosting the Elsewhere web app and backend on Render.
  • ElevenLabs — Best Use of ElevenLabs: Generating AI narration for the Elsewhere product demo.
  • Entire — Best Use of Entire: Sharing the DevRelay session documenting Elsewhere's architecture and local LLM integration.
  • GitHub — Best Use of GitHub Copilot: Using Copilot to inspect the codebase, trace suggestion generation, and test the local LLM integration.

🌍 What's Next?

The next step is to verify the full deployed inference path and browser experience, then continue refining how the app turns a person's interests and available time into a genuinely useful suggestion.

The goal isn't to build the biggest AI application.

It's to build one that gives someone a good reason to close it.

Less scrolling. More elsewhere.

If you try it, I'd love to hear: Would one personalized outdoor suggestion actually get you off your screen?

Top comments (0)