/how-to-build-replit

How to Build a Polls and surveys with Replit

Learn how to build interactive polls and surveys with Replit using simple code examples to engage users and collect valuable feedback online

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

How to Build a Polls and surveys with Replit

To build a simple and functional polls and surveys app on Replit, you can use a small Node.js + Express backend and a basic HTML/JavaScript frontend served from the same project. You’ll collect votes/survey responses using HTTP endpoints, store them in a JSON file or small database (like Replit’s built-in Database), and render results dynamically. The setup works fully inside Replit without external configuration, and you can expand it later to connect to a frontend library like React or a SQL database via Replit Secrets.

 

Project Setup on Replit

 

Create a new Replit project using the Node.js template. Replit automatically creates three main files for you:

  • index.js – this is your server entry file, runs automatically when you click “Run”.
  • package.json – tracks dependencies.
  • Replit UI files – such as replit.nix or hidden config, you don’t need to touch those now.

 

npm install express body-parser @replit/database

 

This command installs:

  • express: lightweight web server framework.
  • body-parser: lets you handle form data or JSON in HTTP requests.
  • @replit/database: simple key-value database provided by Replit.

 

Create Files

 

Add a new folder named public in your Replit file tree. Inside it, create a file named index.html. This will be the visible poll page in your browser.

 

Backend – index.js

 

// index.js
const express = require('express')
const bodyParser = require('body-parser')
const Database = require('@replit/database')

const app = express()
const db = new Database()

app.use(bodyParser.json())
app.use(express.static('public')) // serve files from /public folder

// Endpoint to get poll results
app.get('/results', async (req, res) => {
  const data = await db.get('poll') || { optionA: 0, optionB: 0 }
  res.json(data)
})

// Endpoint to submit a vote
app.post('/vote', async (req, res) => {
  const { choice } = req.body
  let data = await db.get('poll') || { optionA: 0, optionB: 0 }

  if (choice === 'A') data.optionA++
  if (choice === 'B') data.optionB++

  await db.set('poll', data)
  res.json(data)
})

app.listen(3000, () => console.log('Server running on http://localhost:3000'))

 

Place this in your existing index.js file. It sets up a small server that:

  • Serves your frontend (HTML/JS).
  • Has two endpoints: /vote for posting votes, /results for fetching results.
  • Stores results persistently using Replit Database.

 

Frontend – public/index.html

 

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Poll</title>
  </head>
  <body>
    <h1>Favorite Color Poll</h1>
    <button id="voteA">Vote for Blue</button>
    <button id="voteB">Vote for Green</button>

    <h2>Results:</h2>
    <p id="results">Loading...</p>

    <script>
      async function fetchResults() {
        const res = await fetch('/results')
        const data = await res.json()
        document.getElementById('results').textContent =
          `Blue: ${data.optionA} | Green: ${data.optionB}`
      }

      async function vote(choice) {
        await fetch('/vote', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ choice })
        })
        fetchResults()
      }

      document.getElementById('voteA').onclick = () => vote('A')
      document.getElementById('voteB').onclick = () => vote('B')

      // initial load
      fetchResults()
    </script>
  </body>
</html>

 

Place this code inside public/index.html. It connects to your backend, sends votes as JSON, and continuously updates results. Replit automatically makes your server reachable via a public URL once you press “Run”.

 

How It Works Together

 

  • index.js runs the server on port 3000 and exposes routes.
  • public/index.html is automatically served via Express’s express.static().
  • Replit Database saves poll results persistently, even after stopping your Repl.

 

Secrets and Scaling Notes

 

  • To secure data or connect to external databases/APIs, store keys in Replit’s Secrets tab (on left sidebar icon “🔒”). You can then access them in code as process.env.YOUR_KEY_NAME.
  • Replit projects sleep when inactive on free plans; to keep it live, upgrade to Always On via Replit Deployments.
  • For team work, use the built-in multiplayer feature so others can edit simultaneously.

 

This approach works well for small to moderate surveys or classroom polls. You can later extend it to track users, allow multiple questions, or even use a front-end framework like React by adding a client folder — but this foundation already gives you a fully functioning backend and frontend setup that runs entirely inside Replit with persistent storage.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Contact Us

How to Build a Simple Polls API with Express and SQLite on Replit





  
    
  

How to Forward Poll Responses to an External Analytics API on Replit





  
    
  

How to Add Real-Time Poll Updates with Server-Sent Events (SSE)





  
    
  

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Contact Us
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Best Practices for Building a Polls and surveys with Replit

A good, reliable way to build polls and surveys on Replit is to separate your project into a small backend API (using Node.js + Express) and a simple frontend (HTML + JavaScript) that talks to that API. The backend should safely store poll data in a JSON file or a small database like Replit’s built-in Data storage or SQLite. You should use Replit’s Secrets for anything private, make sure your web server listens on process.env.PORT, and manage routes so your frontend and backend communicate cleanly. Avoid trying to handle everything inside one giant file — structure it like a real-world project, even on Replit.

 

Project Structure

 

Inside your Replit project, create the following structure:

  • index.js → main server file (Node.js + Express backend)
  • public/ → directory where you put your static frontend (HTML, CSS, JS)
  • public/index.html → poll webpage
  • data.json → file for storing poll results (if you don’t use a database)
  • .replit → file that tells Replit to run “node index.js”

 

Create the Backend (index.js)

 

In Replit, click the “+” icon to create a new file named index.js. Add this code:

 

// index.js
import express from "express";
import fs from "fs"; 
import path from "path";

const app = express();
const port = process.env.PORT || 3000;

// Middleware to serve static files and handle JSON requests
app.use(express.static("public"));
app.use(express.json());

// Load existing poll data from data.json or create an empty object
const dataFile = path.resolve("data.json");
let polls = {};
if (fs.existsSync(dataFile)) {
  polls = JSON.parse(fs.readFileSync(dataFile));
}

// Get all polls
app.get("/api/polls", (req, res) => {
  res.json(polls);
});

// Create or vote on a poll
app.post("/api/polls", (req, res) => {
  const { question, option } = req.body;

  if (!question || !option) {
    return res.status(400).json({ message: "Missing fields" });
  }

  if (!polls[question]) {
    polls[question] = {};
  }

  if (!polls[question][option]) {
    polls[question][option] = 0;
  }

  polls[question][option]++;

  fs.writeFileSync(dataFile, JSON.stringify(polls, null, 2));

  res.json({ success: true, polls });
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

 

This file:

  • Starts an Express server
  • Serves your frontend from the public folder
  • Provides a small API for creating and voting on polls
  • Saves poll data into data.json (you’ll see this appear automatically)

 

Create the Frontend (public/index.html)

 

In your public folder, create a new file called index.html and paste:

 

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Replit Poll App</title>
    <style>
      body { font-family: Arial; margin: 20px; }
      input, button { margin: 5px; }
    </style>
  </head>
  <body>
    <h1>Create or Vote on a Poll</h1>

    <label>Question: </label>
    <input id="question" placeholder="What's your favorite fruit?" /><br />

    <label>Option: </label>
    <input id="option" placeholder="Apple, Banana, etc." /><br />

    <button id="vote">Submit Vote</button>

    <h2>Current Polls</h2>
    <pre id="output"></pre>

    <script>
      async function loadPolls() {
        const res = await fetch("/api/polls");
        const data = await res.json();
        document.getElementById("output").textContent = JSON.stringify(data, null, 2);
      }

      document.getElementById("vote").onclick = async () => {
        const question = document.getElementById("question").value;
        const option = document.getElementById("option").value;

        await fetch("/api/polls", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ question, option })
        });

        await loadPolls();
      };

      loadPolls();
    </script>
  </body>
</html>

 

This script uses fetch() to call the backend API, display polls, and update results directly from the browser — no page reloads needed.

 

Setup Notes for Replit

 

  • In your Replit sidebar, open the Secrets tab (the lock icon) if you want to hide any API keys or database URLs — don’t hardcode them in your code.
  • Make sure your .replit file includes:

 

run = "node index.js"

 

  • Your server will be available on the Replit live URL (it shows automatically when you click “Run”).
  • You can open the web view inside Replit or click “Open in new tab” for a separate browser tab.

 

Best Practices & Gotchas

 

  • Always write changes to data.json from server-side code — not directly from frontend code. Otherwise, you’ll lose data when Replit restarts.
  • Use async operations for databases or remote APIs to avoid blocking your Replit instance.
  • Keep secrets and tokens in Replit Secrets (Environment Variables). Never commit them to GitHub.
  • Use try/catch blocks for saving and reading files — Replit can recycle containers, and missing files happen.
  • Clean up your Repl occasionally (delete stray test files, restart when weird errors occur, or kill runaway Repls from the console).
  • Think of Replit’s file system as temporary for real projects. For long-term polls, connect to a persistent external database like Supabase, MongoDB Atlas, or Replit DB.

 

Once everything runs, you’ll have a live, interactive polls and survey app right inside Replit that saves results on the backend and updates in real time from the browser — perfect for demos, class projects, or small community forms.

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022