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

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
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.
Create a new Replit project using the Node.js template. Replit automatically creates three main files for you:
replit.nix or hidden config, you don’t need to touch those now.
npm install express body-parser @replit/database
This command installs:
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.
// 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:
/vote for posting votes, /results for fetching results.
<!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”.
express.static().
process.env.YOUR_KEY_NAME.
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.

Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
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.
Inside your Replit project, create the following structure:
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:
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.
run = "node index.js"
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.
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.