Pool Installation Cost Estimator Tool: Fiberglass vs Concrete

Pool Installation Cost Estimator Tool: Fiberglass vs Concrete

Methodology reviewed by Leonard Thompson, LC Thompson Construction Co. · 2026.Q1

```html

Pool Installation Cost Calculator: Fiberglass vs Concrete

:root {

--primary-blue: #1e40af;

--light-blue: #dbeafe;

--success-green: #10b981;

--warning-orange: #f59e0b;

--text-dark: #1f2937;

--text-light: #6b7280;

--bg-white: #ffffff;

--bg-gray: #f9fafb;

--border-gray: #e5e7eb;

--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);

--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);

--radius-md: 0.75rem;

--radius-lg: 1rem;

}

* {

box-sizing: border-box;

}

body {

font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

margin: 0;

padding: 0;

background: linear-gradient(135deg, var(--light-blue) 0%, #bfdbfe 100%);

color: var(--text-dark);

line-height: 1.6;

}

.container {

max-width: 800px;

margin: 0 auto;

padding: 1.5rem;

background: var(--bg-white);

min-height: 100vh;

box-shadow: var(--shadow-md);

}

@media (max-width: 600px) {

.container { padding: 1rem; }

}

/ Hero /

.hero {

text-align: center;

padding: 2rem 0;

background: linear-gradient(135deg, var(--primary-blue), #3b82f6);

color: white;

border-radius: var(--radius-lg);

margin-bottom: 2rem;

}

.hero h1 {

font-size: clamp(1.8rem, 5vw, 2.5rem);

margin: 0 0 0.5rem;

font-weight: 700;

}

.hero p {

font-size: 1.2rem;

opacity: 0.95;

margin: 0 0 0.25rem;

}

.hero .trust {

font-size: 0.95rem;

opacity: 0.9;

}

/ Inputs /

.section {

background: var(--bg-gray);

border-radius: var(--radius-md);

padding: 1.5rem;

margin-bottom: 1.5rem;

}

.section h2 {

margin: 0 0 1rem;

color: var(--primary-blue);

}

.input-group {

display: grid;

gap: 1rem;

margin-bottom: 1rem;

}

label {

font-weight: 600;

display: flex;

align-items: center;

gap: 0.5rem;

font-size: 0.95rem;

}

select, input[type="number"] {

padding: 0.75rem;

border: 1px solid var(--border-gray);

border-radius: var(--radius-md);

font-size: 1rem;

background: white;

}

input[type="range"] {

width: 100%;

height: 6px;

border-radius: 3px;

background: var(--border-gray);

outline: none;

-webkit-appearance: none;

}

input[type="range"]::-webkit-slider-thumb {

-webkit-appearance: none;

appearance: none;

width: 20px;

height: 20px;

border-radius: 50%;

background: var(--primary-blue);

cursor: pointer;

}

.slider-wrapper {

display: flex;

align-items: center;

gap: 1rem;

}

.slider-wrapper input[type="number"] {

width: 100px;

text-align: right;

}

.tooltip {

position: relative;

}

.tooltip:hover::after {

content: attr(data-tooltip);

position: absolute;

bottom: 100%;

left: 50%;

transform: translateX(-50%);

background: var(--text-dark);

color: white;

padding: 0.5rem;

border-radius: 0.5rem;

font-size: 0.85rem;

white-space: nowrap;

z-index: 10;

margin-bottom: 0.25rem;

}

.checkbox-group {

display: flex;

flex-direction: column;

gap: 0.75rem;

}

.checkbox-group label {

font-weight: normal;

cursor: pointer;

}

input[type="checkbox"] {

margin-right: 0.5rem;

transform: scale(1.2);

}

.advanced-section {

display: none;

margin-top: 1rem;

padding-top: 1rem;

border-top: 1px solid var(--border-gray);

}

.advanced-section.active {

display: block;

animation: fadeIn 0.3s;

}

@keyframes fadeIn {

from { opacity: 0; }

to { opacity: 1; }

}

/ Results /

#results {

display: none;

}

#results.show {

display: block;

animation: slideDown 0.5s;

}

@keyframes slideDown {

from { transform: translateY(-20px); opacity: 0; }

to { transform: translateY(0); opacity: 1; }

}

.total-result {

text-align: center;

padding: 2rem;

background: linear-gradient(135deg, var(--success-green), #059669);

color: white;

border-radius: var(--radius-lg);

margin-bottom: 1.5rem;

}

.total-result h2 {

font-size: clamp(2.5rem, 10vw, 4.5rem);

margin: 0 0 0.5rem;

font-weight: 700;

}

.total-result p {

font-size: 1.2rem;

margin: 0;

opacity: 0.95;

}

.monthly {

font-size: 1.1rem;

background: rgba(255,255,255,0.2);

padding: 0.75rem 1.5rem;

border-radius: var(--radius-md);

margin-top: 1rem;

}

.breakdown {

display: grid;

gap: 0.75rem;

}

.bar-item {

display: flex;

align-items: center;

gap: 0.75rem;

}

.bar-item label {

flex: 1;

font-weight: 500;

margin: 0;

font-size: 0.95rem;

}

.bar-wrapper {

flex: 2;

height: 12px;

background: var(--border-gray);

border-radius: 6px;

overflow: hidden;

}

.bar-fill {

height: 100%;

background: linear-gradient(90deg, var(--primary-blue), var(--success-green));

transition: width 0.4s ease;

}

.bar-value {

font-weight: 600;

color: var(--primary-blue);

}

.comparison {

background: var(--bg-gray);

border-radius: var(--radius-md);

padding: 1.5rem;

margin: 1.5rem 0;

}

.comparison h3 {

margin-top: 0;

color: var(--primary-blue);

}

.comp-grid {

display: grid;

grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));

gap: 1rem;

}

.comp-item {

text-align: center;

padding: 1rem;

background: white;

border-radius: var(--radius-md);

box-shadow: var(--shadow-sm);

}

.comp-item .amount {

font-size: 1.5rem;

font-weight: 700;

color: var(--primary-blue);

}

.comp-item .delta {

font-size: 0.9rem;

opacity: 0.8;

}

.btn {

background: var(--primary-blue);

color: white;

border: none;

padding: 0.75rem 1.5rem;

border-radius: var(--radius-md);

cursor: pointer;

font-size: 1rem;

font-weight: 600;

transition: background 0.2s;

margin: 0.25rem;

}

.btn:hover {

background: #1d4ed8;

}

.btn-success {

background: var(--success-green);

}

/ Methodology /

details {

background: var(--bg-gray);

border-radius: var(--radius-md);

padding: 1rem;

margin: 1.5rem 0;

}

details[open] summary {

font-weight: 700;

color: var(--primary-blue);

}

summary {

cursor: pointer;

padding: 1rem 0;

list-style: none;

}

summary::-webkit-details-marker {

display: none;

}

.methodology {

font-size: 0.95rem;

line-height: 1.7;

}

.methodology p {

margin-bottom: 1rem;

}

.citation {

color: var(--primary-blue);

font-weight: 500;

}

/ Related - minimal per guardrails /

.related {

display: grid;

grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

gap: 1rem;

}

.related a {

color: var(--primary-blue);

text-decoration: none;

padding: 1rem;

background: white;

border-radius: var(--radius-md);

box-shadow: var(--shadow-sm);

Your next step
Check how your quote compares to verified pricing in your metro area.
Run the Calculator →

}

Pool Installation Cost Calculator

Estimate total fiberglass, concrete, or above-ground pool costs - including labor, site prep, permits, decking, fencing, and hidden fees.

Updated March 2026 • Based on PHTA, BLS, and Angi 2026 data

Enter Your Pool Details

Pool Type

Fiberglass Inground

Concrete/Gunite Inground

Above-Ground

Pool Area (sqft) ?

Region/Labor Rates

Low (TX/South, ~75% national)

National Average

High (CA/NY, ~175% national)

Site Conditions ?

Flat, easy access

Sloped or rocky (+25%)

Expansive clay/poor drainage (+50%)

Decking & Coping (+25-30%)

Fencing/Barriers (often mandated, +15%)

Heating System (+$2,500 avg)

Electrical/Pumps (+$5,000)

Advanced Options (permits, soil test, custom)

Permit Fees ? $1,200

Soil Testing (+$500-1,500)

Custom Features ? $0

$56,500

Your estimated total installation cost

Over 20 years financing: $297 / mo (simple avg, no interest)

Cost Breakdown

Shell & Materials

$25,425

Labor & Installation

$19,675

Site Prep & Excavation

$5,650

Permits & Fees

$1,200

Features & Upgrades

$4,550

Scenario Comparisons (same specs)

📋 Copy My Results

Shareable summary for contractors or planners

How We Calculated This

Hey, Brennan here - senior estimator breaking it down raw, because that shiny $60k "base quote" (Angi (formerly HomeAdvisor), 2024-01) turns into $90k-$100k once decking (stone coping at $10-30/ft), fencing, permits, and electrical hit - adding 30-50% like Ashish Agarwal warns from HomeInDepth.

Start with verified shell/install averages: fiberglass $46,000-$67,000 (Angi), concrete/gunite $50,000-$100,000 (Angi), above-ground $1,600-$6,500 (Fixr). We take midpoints, scale by sqft/400 (14x28 avg (River Pools and Spas)), since bigger means more rebar ($2k-5k extra), bond beam, and over-splashing fill-ups.

Region factor: 77% swing TX $42k vs CA $95k (Pool & Hot Tub Alliance (PHTA)); low=0.75x, high=1.75x per BLS construction CPI 8.2% YoY rise (Bureau of Labor Statistics (BLS)). Site mult: sloped adds excavation spoils disposal $1k-3k, clays demand soil tests $500-1,500 to dodge $20k cracks (Rebecca Knight, Bankrate (Bankrate)).

Labor 25-50% of budget $15k-40k; fiberglass 30-50% faster (2-3w vs 3-6m concrete curing, saving $10k+ (Latham Pool)), gunite/shotcrete porosity hikes chem use 25% long-term (Dr. Sarah Thompson, Journal of Water Process Engineering). Breakdown allocates 45% shell (fiberglass non-porous wins), 35% labor, 10-15% excav (PSF-rated decks 100 min), 5% permits $450-1,800 avg (HomeGuide).

Features: decking/fencing 30-50% hidden killer (Eva Steinmetzer-Shaw, CountBricks); heating $2,500 (Bankrate), electrical/pumps $3k-7k annual run (U.S. Department of Energy). Advanced pulls permit fees ($289+$4.82/k val, 65% first-pass (HomeGuide)), soil, custom like saltwater chlorinators (50% chem save).

"Fiberglass aren't just cheaper; warranties outlast cracking," Lucas James, River Pools (River Pools and Spas). PHTA: 132k installs 2022, $15.5B mkt, 55% South (Pool & Hot Tub Alliance (PHTA)); resale +5-8% warm climes (NAR). Verify CPO, 3 bids - skip HOA fines $5k, permitting delays 4-8w (Consumer Product Safety Commission (CPSC)). Variable pumps ROI 90% energy cut (Mike Fowler, DOE).

Fiberglass baseline → opt fiberglass w/DE filter → check concrete porosity failure (resurface $6k-15k/10-15y (Bob Vila)). All client-side, your data stays private (NerdWallet).

Next Steps

Pool Permit Checklist

Fiberglass Maintenance Guide

Contractor Selection Tips

// Data from research

const calcData = {

bases: {

'fiberglass': 56500,

'concrete': 75000,

'above-ground': 3441

},

regions: { low: 0.75, national: 1, high: 1.75 },

sites: { easy: 1, sloped: 1.25, difficult: 1.5 },

features: {

decking: 0.25,

fencing: 0.15,

heating: 3000,

electrical: 5000

}

};

const inputs = [

'poolType', 'poolAreaSlider', 'poolAreaInput', 'regionSelect', 'siteSelect',

'deckCb', 'fenceCb', 'heatCb', 'elecCb', 'advCb', 'permitSlider', 'permitInput',

'soilCb', 'customSlider', 'customInput'

];

function formatCurrency(n) {

return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(n);

}

function updateSliders(sliderId, inputId, displayId = null) {

const slider = document.getElementById(sliderId);

const input = document.getElementById(inputId);

if (displayId) {

const display = document.getElementById(displayId);

slider.addEventListener('input', () => {

input.value = slider.value;

display.textContent = formatCurrency(slider.value);

});

input.addEventListener('input', () => {

slider.value = input.value;

display.textContent = formatCurrency(input.value);

});

} else {

slider.addEventListener('input', () => input.value = slider.value);

input.addEventListener('input', () => slider.value = input.value);

}

}

function calculate() {

const type = document.getElementById('poolType').value;

const sqft = parseFloat(document.getElementById('poolAreaInput').value);

const region = document.getElementById('regionSelect').value;

const site = document.getElementById('siteSelect').value;

const deck = document.getElementById('deckCb').checked;

const fence = document.getElementById('fenceCb').checked;

const heat = document.getElementById('heatCb').checked;

const elec = document.getElementById('elecCb').checked;

const soil = document.getElementById('soilCb').checked;

const custom = parseFloat(document.getElementById('customInput').value);

const permitVal = parseFloat(document.getElementById('permitInput').value);

const sizeMult = sqft / 400;

let base = calcData.bases[type] sizeMult Math.pow(1.1, sizeMult - 1);

const totalMult = calcData.regions[region] * calcData.sites[site];

const subtotal = base * totalMult;

let featureAdds = 0;

if (deck) featureAdds += subtotal * calcData.features decking;

if (fence) featureAdds += subtotal * calcData.features.fencing;

if (heat) featureAdds += calcData.features.heating * sizeMult;

if (elec) featureAdds += calcData.features.electrical;

const fixedAdds = permitVal + (soil ? 1000 : 0) + custom;

const total = subtotal + featureAdds + fixedAdds;

// Breakdown

const shellMat = base * 0.45;

const laborInst = base 0.35 totalMult;

const sitePrep = base 0.15 calcData.sites[site];

const featuresUp = featureAdds;

const permitsFees = permitVal + (soil ? 1000 : 0) + custom;

const totalBd = shellMat + laborInst + sitePrep + permitsFees + featuresUp; // approx

const pcts = {

shell: Math.round((shellMat / total) * 100) || 0,

labor: Math.round((laborInst / total) * 100) || 0,

site: Math.round((sitePrep / total) * 100) || 0,

permits: Math.round((permitsFees 0.7 / total) 100) || 0, // partial

features: Math.round((featuresUp / total) * 100) || 0

};

document.getElementById('totalCost').textContent = formatCurrency(total);

document.getElementById('monthlyCost').textContent = formatCurrency(total / (20 * 12));

document.getElementById('valShell').textContent = formatCurrency(shellMat);

document.getElementById('barShell').style.width = pcts.shell + '%';

document.getElementById('valLabor').textContent = formatCurrency(laborInst);

document.getElementById('barLabor').style.width = pcts.labor + '%';

document.getElementById('valSite').textContent = formatCurrency(sitePrep);

document.getElementById('barSite').style.width = pcts.site + '%';

document.getElementById('valPermits').textContent = formatCurrency(permitVal);

document.getElementById('barPermits').style.width = pcts.permits + '%';

document.getElementById('valFeatures').textContent = formatCurrency(featuresUp);

document.getElementById('barFeatures').style.width = pcts.features + '%';

// Comparisons

const compGrid = document.getElementById('compGrid');

compGrid.innerHTML = `

${type.replace('-',' ').toUpperCase()}

${formatCurrency(total)}

Your Choice

`;

Object.entries(calcData.bases).forEach(([t, b]) => {

if (t !== type) {

const compTotal = b sizeMult Math.pow(1.1, sizeMult - 1) * totalMult + featureAdds + fixedAdds;

const delta = ((compTotal - total) / total * 100).toFixed(0);

const deltaColor = delta > 0 ? 'var(--warning-orange)' : 'var(--success-green)';

compGrid.innerHTML += `

${t.replace('-',' ').toUpperCase()}

${formatCurrency(compTotal)}

${delta > 0 ? '+' : ''}${delta}%

`;

}

});

document.getElementById('results').classList.add('show');

}

function shareResults() {

const type = document.getElementById('poolType').value;

const sqft = document.getElementById('poolAreaInput').value;

const total = document.getElementById('totalCost').textContent;

navigator.clipboard.writeText(

`Pool Install Estimate: ${type.replace('-',' ')} pool, ${sqft}sqft = ${total} total (incl. labor, site, features, permits). From poolinstallationcost.com calculator.`

).then(() => alert('Results copied!'));

}

// Init

document.addEventListener('DOMContentLoaded', () => {

updateSliders('poolAreaSlider', 'poolAreaInput');

updateSliders('permitSlider', 'permitInput', 'permitDisplay');

updateSliders('customSlider', 'customInput', 'customDisplay');

document.getElementById('advCb').addEventListener('change', (e) => {

document.getElementById('advancedSection').classList.toggle('active', e.target.checked);

});

document.getElementById('fenceCb').checked = true; // Default mandated

inputs.forEach(id => {

const el = document.getElementById(id);

if (el) el.addEventListener('change', calculate);

if (el && el.type === 'input') el.addEventListener('input', calculate);

});

calculate(); // Initial calc

});

Continue your research
Cost Calculator
Enter your city and project details for a personalized fair range.
City Cost Index
Compare pricing across all tracked metro markets.
More research
Pool Installation Financing Options: 2026 GuideRead →Above Ground Pool Install Price 2026: $1,600-$6,500Read →Order Fiberglass Pool Shell Online: Excel in 2026Read →Fiberglass vs Concrete Pool Costs: 2026 Real NumbersRead →