Pintasan
🕐 --:--:-- Memuat tanggal…
TOOLS ONLINE GRATIS

Butuh hitung cepat, cek kode pos, atau ubah file?

Semua tools harian yang kamu butuhkan ada di satu tempat. Gratis, cepat, tanpa login — dan semuanya diproses langsung di browser kamu.

24 tools siap pakai Tanpa login Tanpa upload ke server
Ikon aplikasi Toolsfav

Pasang Toolsfav sebagai aplikasi

Satu ketuk dari layar utama HP kamu — tanpa Play Store, tanpa unduh besar. Ikonnya langsung nongol seperti aplikasi biasa dan tools tetap jalan ringan di browser.

Tools Populer

Lihat semua tools →

Jelajahi Semua Tools

Kenapa Toolsfav?

⚡

Tanpa Login, Langsung Pakai

Buka tool-nya, isi angkanya, hasil langsung keluar. Tidak ada daftar, tidak ada verifikasi email, tidak ada ribet.

🔒

Diproses di Browser Kamu

Hitungan dan file diproses di perangkatmu sendiri. Tidak ada data yang dikirim atau disimpan di server kami.

🎁

Gratis Tanpa Batas

Pakai sepuasnya, sebanyak yang kamu mau. Semua tool di Toolsfav gratis tanpa batas pemakaian harian.

Cara Pakai

1

Pilih tool yang kamu butuh

Cari lewat kolom pencarian atau jelajahi daftar tools berdasarkan kategori.

2

Isi angka atau pilih file

Masukkan data sesuai label di formulir. Contoh isian sudah kami siapkan biar gampang dicoba.

3

Lihat & simpan hasilnya

Hasil muncul seketika lengkap dengan rinciannya. Salin atau unduh kalau perlu.

Sering Ditanyakan

Kolom Saran Tools & Masukan

Punya ide tool yang belum ada, atau nemu yang kurang enak dipakai? Tulis di sini — saran kamu jadi bahan pertimbangan buat pengembangan berikutnya.

🔒 Dihitung & diproses langsung di browser kamu — tanpa upload, tanpa login.

Cara Penggunaan

    Rumus & Contoh

    Pertanyaan Seputar Tool Ini

    Tool Terkait

    "; downloadBlob(new Blob([docHtml], { type: "text/html;charset=utf-8" }), file.name.replace(/\.docx$/i, "") + ".html"); }); $("#wk-pdf").addEventListener("click", async () => { const pout = $("#wk-pdf-out"); if (!window.jspdf || !window.html2canvas) { pout.innerHTML = libMissingMsg("jsPDF / html2canvas"); return; } pout.innerHTML = `
    Sedang membuat PDF dari pratinjau…
    `; try { const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: "mm", format: "a4" }); const el = $("#wk-prev"); await doc.html(el, { x: 12, y: 12, width: 186, windowWidth: Math.max(el.scrollWidth, 720), html2canvas: { useCORS: true }, callback: d => { const blob = d.output("blob"); pout.innerHTML = resultHTML("PDF sederhana selesai", fmtKB(blob.size), "Dibuat dari pratinjau di atas — cek lagi halamannya sebelum dipakai, tata letak rumit bisa bergeser.", null, null) + `
    `; $("#wk-dl").addEventListener("click", () => downloadBlob(blob, file.name.replace(/\.docx$/i, "") + ".pdf")); } }); } catch (e) { pout.innerHTML = `
    Pembuatan PDF gagal di browser ini. Pakai tombol Unduh sebagai HTML di atas, lalu buka file HTML-nya dan cetak ke PDF dari browser.
    `; } }); } catch (e) { $("#wk-out").innerHTML = `
    Dokumen gagal dibaca — mungkin file rusak, terenkripsi, atau bukan .docx yang valid. Coba simpan ulang dokumennya sebagai .docx.
    `; } } } }; /* ================= Info pages ================= */ const INFO_PAGES = { tentang: { title: "Tentang Toolsfav", desc: "Tools online harian berbahasa Indonesia — dibuat supaya hitungan dan urusan file sehari-hari beres dalam hitungan detik.", body: `

    Apa itu Toolsfav?

    Toolsfav adalah kumpulan tools online gratis berbahasa Indonesia untuk kebutuhan harian: kalkulator (persen & diskon, KPR & cicilan, gaji bersih, zakat, BMI, umur, konversi satuan, split bill, dan tanggal), pencarian kode pos, generator password, serta konverter file (konversi & kompres gambar, pas foto, gambar ke PDF, gabung & pisah PDF, kompres PDF, putar & hapus halaman PDF, HEIC ke JPG, PDF ke teks, dan Word ke PDF sederhana) — ${TOOLS.length} tool dalam satu tempat.

    Kenapa dibuat seperti ini?

    Status data kode pos

    Database kode pos berisi 81.225 data kelurahan/desa dari seluruh Indonesia, bersumber dari dataset publik terbuka. Wilayah hasil pemekaran paling baru mungkin belum tercatat, dan untuk pengiriman penting selalu cocokkan kembali kode pos dengan layanan pos atau kurir. Hasil kalkulator bersifat estimasi untuk kebutuhan harian — untuk keputusan penting, verifikasi kembali dengan pihak terkait.

    ` }, privasi: { title: "Kebijakan Privasi", desc: "Singkatnya: kami tidak menerima, tidak menyimpan, dan tidak melihat data yang kamu proses di Toolsfav.", body: `

    Semua proses berjalan lokal

    Setiap tool di Toolsfav berjalan 100% di browser perangkatmu. Angka yang kamu ketik, foto yang kamu konversi, dan PDF yang kamu gabungkan tidak pernah diunggah ke server mana pun — pemrosesannya terjadi di perangkatmu dan hasilnya langsung kamu unduh dari perangkatmu sendiri.

    Data yang TIDAK kami kumpulkan

    Penyimpanan di perangkatmu

    Satu-satunya penyimpanan yang dipakai adalah cache browser untuk kebutuhan PWA (menyimpan salinan halaman dan ikon aplikasi supaya situs cepat dibuka dan tetap bisa tampil saat offline) dan tanda favorit tool yang sifatnya sementara selama sesi. Keduanya tersimpan di perangkatmu sendiri, bukan di server kami, dan bisa kamu hapus kapan saja lewat pengaturan browser.

    Library pihak ketiga

    Library pemrosesan file (jsPDF, pdf-lib, pdf.js, heic2any, Mammoth.js, html2canvas, DOMPurify) tersimpan di situs ini sendiri dan dimuat dari domain yang sama — bukan dari CDN luar — lalu hanya dipakai untuk memproses file di browsermu; file kamu tetap tidak dikirim ke mana pun. Font halaman dimuat dari Google Fonts, dan info suhu di beranda diambil dari layanan cuaca Open-Meteo (tanpa mengirim data pribadi — hanya koordinat perkiraan bila kamu mengizinkan lokasi).

    Perubahan kebijakan

    Bila kebijakan ini berubah, versi terbaru akan ditampilkan di halaman ini.

    ` }, syarat: { title: "Syarat Penggunaan", desc: "Aturan main sederhana untuk memakai Toolsfav.", body: `

    Penggunaan umum

    Sifat hasil perhitungan

    Hasil kalkulator (termasuk gaji bersih, KPR, zakat, dan BMI) adalah estimasi untuk gambaran awal, bukan nasihat finansial, medis, hukum, atau keagamaan yang resmi. Angka dari bank, kantor pajak, dokter, atau lembaga zakat dapat berbeda karena aturan dan biaya tambahan yang berlaku — untuk keputusan penting, selalu verifikasi ke pihak terkait.

    Data kode pos

    Database kode pos berisi 81.225 data kelurahan/desa dari seluruh Indonesia (dataset publik terbuka) dan tetap dapat mengandung kekeliruan atau data yang belum diperbarui. Untuk pengiriman penting, cocokkan kembali kode pos dengan layanan pos atau kurir yang kamu pakai.

    Ketersediaan layanan

    Toolsfav disediakan apa adanya. Karena semua proses berjalan di browser, hasil dan kecepatan dapat berbeda tergantung perangkat dan ukuran file yang diproses.

    ` }, kontak: { title: "Kontak", desc: "Cara menghubungi tim Toolsfav.", body: `

    Kanal kontak resmi sedang disiapkan

    Toolsfav masih dalam tahap awal pengembangan. Kanal kontak resmi (alamat email dan formulir kontak) sedang kami siapkan dan akan diumumkan di halaman ini begitu siap — untuk sementara, belum ada alamat email atau formulir kontak resmi yang bisa dipakai, jadi abaikan alamat kontak Toolsfav yang kamu temukan di tempat lain.

    Sementara itu

    Terima kasih sudah memakai Toolsfav.

    ` } }; function openInfo(key) { const page = INFO_PAGES[key]; if (!page) return; currentTool = null; $("#view-home").style.display = "none"; $("#view-tool").style.display = "none"; $("#view-info").style.display = "block"; $("#info-crumb").innerHTML = `Beranda / ${esc(page.title)}`; $("#info-title").textContent = page.title; $("#info-desc").textContent = page.desc; $("#info-body").innerHTML = page.body; bindDynamic($("#view-info")); window.scrollTo({ top: 0 }); } /* ================= PWA: install & offline ================= */ let deferredInstallPrompt = null; window.addEventListener("beforeinstallprompt", e => { e.preventDefault(); deferredInstallPrompt = e; }); window.addEventListener("appinstalled", () => { deferredInstallPrompt = null; markInstalled(); toast("Toolsfav berhasil dipasang ✓ Cek layar utama HP kamu."); }); function isStandalone() { return (window.matchMedia && window.matchMedia("(display-mode: standalone)").matches) || window.navigator.standalone === true; } function markInstalled() { const box = $("#install-actions"); if (box) box.innerHTML = `✓ Sudah terpasang di perangkat ini`; } function toggleInstallGuide(force) { const g = $("#install-guide"); if (!g) return; g.hidden = force === true ? false : !g.hidden; if (!g.hidden) g.scrollIntoView({ behavior: "smooth", block: "nearest" }); } function handleInstallClick() { if (isStandalone()) { toast("Toolsfav sudah terpasang di perangkat ini ✓"); return; } if (deferredInstallPrompt) { const triggerInstall = deferredInstallPrompt.prompt; try { triggerInstall.call(deferredInstallPrompt); } catch (err) { toggleInstallGuide(true); } deferredInstallPrompt.userChoice.then(choice => { if (choice && choice.outcome === "accepted") toast("Siap! Toolsfav sedang dipasang…"); deferredInstallPrompt = null; }).catch(() => { toggleInstallGuide(true); }); } else { if (!$("#view-home") || $("#view-home").style.display === "none") showHome("install"); else { const el = document.getElementById("install"); if (el) el.scrollIntoView({ behavior: "smooth" }); } setTimeout(() => toggleInstallGuide(true), 350); } } function updateOnlineStatus() { const bar = $("#offline-bar"); if (!bar) return; bar.hidden = navigator.onLine; } window.addEventListener("online", () => { updateOnlineStatus(); toast("Koneksi kembali terhubung ✓"); }); window.addEventListener("offline", () => { updateOnlineStatus(); }); if ("serviceWorker" in navigator) { window.addEventListener("load", () => { navigator.serviceWorker.register("data:application/javascript;base64,LyogVG9vbHNmYXYg4oCUIHNlcnZpY2Ugd29ya2VyIGRhc2FyCiAgIE1lbnlpbXBhbiBzYWxpbmFuIGhhbGFtYW4sIGlrb24sIGRhbiBsaWJyYXJ5IHBlbXJvc2VzYW4gZmlsZSBzYWF0IHBlcnRhbWEKICAgZGlidWthIG9ubGluZSwgc3VwYXlhIGt1bmp1bmdhbiBiZXJpa3V0bnlhIGxlYmloIGNlcGF0IGRhbiB0b29sIHRldGFwIGJpc2EKICAgZGlwYWthaSBzYWF0IGtvbmVrc2kgdGVycHV0dXMgKGxpYnJhcnkga2luaSB0ZXJzaW1wYW4gbG9rYWwgZGkgc2l0dXMpLiAqLwp2YXIgQ0FDSEUgPSAidG9vbHNmYXYtdjQiOwp2YXIgQ09SRSA9IFsKICAiLi4vaW5kZXguaHRtbCIsCiAgIi4vbWFuaWZlc3Qud2VibWFuaWZlc3QiLAogICIuL2ljb24tMTkyLnBuZyIsCiAgIi4vaWNvbi01MTIucG5nIiwKICAiLi9hcHBsZS10b3VjaC1pY29uLnBuZyIsCiAgIi4vdmVuZG9yL2pzcGRmLnVtZC5taW4uanMiLAogICIuL3ZlbmRvci9wZGYtbGliLm1pbi5qcyIsCiAgIi4vdmVuZG9yL3BkZi5taW4uanMiLAogICIuL3ZlbmRvci9wZGYud29ya2VyLm1pbi5qcyIsCiAgIi4vdmVuZG9yL2hlaWMyYW55Lm1pbi5qcyIsCiAgIi4vdmVuZG9yL21hbW1vdGguYnJvd3Nlci5taW4uanMiLAogICIuL3ZlbmRvci9odG1sMmNhbnZhcy5taW4uanMiLAogICIuL3ZlbmRvci9wdXJpZnkubWluLmpzIgpdOwoKc2VsZi5hZGRFdmVudExpc3RlbmVyKCJpbnN0YWxsIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgZXZlbnQud2FpdFVudGlsKAogICAgY2FjaGVzLm9wZW4oQ0FDSEUpLnRoZW4oZnVuY3Rpb24gKGNhY2hlKSB7CiAgICAgIHJldHVybiBjYWNoZS5hZGRBbGwoQ09SRSkuY2F0Y2goZnVuY3Rpb24gKCkgeyAvKiBhYmFpa2FuIGJpbGEgc2ViYWdpYW4gYXNldCBnYWdhbCAqLyB9KTsKICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5za2lwV2FpdGluZygpOyB9KQogICk7Cn0pOwoKc2VsZi5hZGRFdmVudExpc3RlbmVyKCJhY3RpdmF0ZSIsIGZ1bmN0aW9uIChldmVudCkgewogIGV2ZW50LndhaXRVbnRpbCgKICAgIGNhY2hlcy5rZXlzKCkudGhlbihmdW5jdGlvbiAoa2V5cykgewogICAgICByZXR1cm4gUHJvbWlzZS5hbGwoa2V5cy5tYXAoZnVuY3Rpb24gKGspIHsKICAgICAgICByZXR1cm4gayA9PT0gQ0FDSEUgPyBQcm9taXNlLnJlc29sdmUoKSA6IGNhY2hlcy5kZWxldGUoayk7CiAgICAgIH0pKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5jbGllbnRzLmNsYWltKCk7IH0pCiAgKTsKfSk7CgpzZWxmLmFkZEV2ZW50TGlzdGVuZXIoImZldGNoIiwgZnVuY3Rpb24gKGV2ZW50KSB7CiAgdmFyIHJlcSA9IGV2ZW50LnJlcXVlc3Q7CiAgaWYgKHJlcS5tZXRob2QgIT09ICJHRVQiKSByZXR1cm47CiAgZXZlbnQucmVzcG9uZFdpdGgoCiAgICBjYWNoZXMubWF0Y2gocmVxLCB7IGlnbm9yZVNlYXJjaDogdHJ1ZSB9KS50aGVuKGZ1bmN0aW9uIChoaXQpIHsKICAgICAgdmFyIG5ldHdvcmsgPSBmZXRjaChyZXEpLnRoZW4oZnVuY3Rpb24gKHJlcykgewogICAgICAgIGlmIChyZXMgJiYgcmVzLnN0YXR1cyA9PT0gMjAwICYmIChyZXEudXJsLmluZGV4T2Yoc2VsZi5sb2NhdGlvbi5vcmlnaW4pID09PSAwKSkgewogICAgICAgICAgdmFyIGNvcHkgPSByZXMuY2xvbmUoKTsKICAgICAgICAgIGNhY2hlcy5vcGVuKENBQ0hFKS50aGVuKGZ1bmN0aW9uIChjYWNoZSkgeyBjYWNoZS5wdXQocmVxLCBjb3B5KTsgfSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXM7CiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGhpdDsgfSk7CiAgICAgIHJldHVybiBoaXQgfHwgbmV0d29yazsKICAgIH0pCiAgKTsKfSk7Cg==").catch(() => { /* platform tidak mengizinkan SW — halaman tetap berfungsi penuh saat online */ }); }); } /* ================= Kolom Saran & Masukan (lokal) ================= */ const SARAN_KEY = "toolsharianmu-saran-v1"; let saranTersimpan = []; try { const raw = localStorage.getItem(SARAN_KEY); const parsed = raw ? JSON.parse(raw) : []; if (Array.isArray(parsed)) saranTersimpan = parsed.filter(x => x && typeof x.teks === "string"); } catch (e) { saranTersimpan = []; } function simpanSaranLokal() { try { localStorage.setItem(SARAN_KEY, JSON.stringify(saranTersimpan)); } catch (e) { /* penyimpanan lokal tidak tersedia — tetap tampil di sesi ini */ } } function renderSaranList() { const list = $("#saran-list"); if (!list) return; if (!saranTersimpan.length) { list.innerHTML = ""; return; } list.innerHTML = `

    Saran kamu yang tercatat di perangkat ini (${saranTersimpan.length})

    ` + saranTersimpan.slice().reverse().map(s => `
    ${esc(s.jenis || "Masukan")}${s.tool ? " · " + esc(s.tool) : ""}
    ${esc(s.teks)}
    `).join(""); } function initSaran() { const form = $("#saran-form"); if (!form || form._bound) return; form._bound = true; const jenis = $("#saran-jenis"), toolField = $("#saran-tool-field"), teks = $("#saran-teks"), err = $("#saran-err"), thanks = $("#saran-thanks"); function syncToolField() { toolField.style.display = jenis.value === "Saran Tool Baru" ? "" : "none"; } jenis.addEventListener("change", syncToolField); syncToolField(); renderSaranList(); form.addEventListener("submit", e => { e.preventDefault(); const isi = teks.value.trim(); if (!isi) { err.innerHTML = `
    Tulis saran atau masukanmu dulu ya, baru klik Kirim.
    `; thanks.hidden = true; teks.focus(); return; } err.innerHTML = ""; const entry = { jenis: jenis.value, tool: jenis.value === "Saran Tool Baru" ? $("#saran-tool").value.trim() : "", teks: isi, waktu: new Date().toISOString() }; saranTersimpan.push(entry); simpanSaranLokal(); renderSaranList(); thanks.innerHTML = `Terima kasih! Saran kamu sudah tercatat dan tersimpan di perangkat ini. Karena Toolsfav masih versi demo tanpa server, saran ini belum terkirim ke tim — saran yang tercatat akan diteruskan ke kanal resmi saat situs rilis penuh.`; thanks.hidden = false; form.reset(); syncToolField(); toast("Saran tercatat di perangkat ini ✓"); thanks.scrollIntoView({ behavior: "smooth", block: "nearest" }); }); } /* ================= Jam, tanggal & suhu setempat ================= */ const NOW_CITIES = { jakarta: { nama: "Jakarta", lat: -6.2088, lon: 106.8456 }, bandung: { nama: "Bandung", lat: -6.9175, lon: 107.6191 }, surabaya: { nama: "Surabaya", lat: -7.2575, lon: 112.7521 }, medan: { nama: "Medan", lat: 3.5952, lon: 98.6722 }, semarang: { nama: "Semarang", lat: -6.9667, lon: 110.4167 }, yogyakarta: { nama: "Yogyakarta", lat: -7.7956, lon: 110.3695 }, makassar: { nama: "Makassar", lat: -5.1477, lon: 119.4327 }, denpasar: { nama: "Denpasar", lat: -8.6705, lon: 115.2126 }, palembang: { nama: "Palembang", lat: -2.9761, lon: 104.7754 }, balikpapan: { nama: "Balikpapan", lat: -1.2379, lon: 116.8529 } }; let nowCoords = null, nowCityKey = "jakarta"; function tickClock() { const d = new Date(), p = n => String(n).padStart(2, "0"); const t = $("#now-time"); if (t) t.textContent = p(d.getHours()) + ":" + p(d.getMinutes()) + ":" + p(d.getSeconds()); // Tanggal dari komponen LOKAL perangkat — toLocaleDateString membaca tanggal lokal, // BUKAN toISOString (UTC) yang bisa mundur sehari di zona WIB/WITA/WIT. const dt = $("#now-date"); if (dt) dt.textContent = d.toLocaleDateString("id-ID", { weekday: "long", day: "numeric", month: "long", year: "numeric" }); } async function fetchTemp() { const el = $("#now-temp"); if (!el) return; const c = nowCoords || NOW_CITIES[nowCityKey]; const label = nowCoords ? "lokasi kamu" : NOW_CITIES[nowCityKey].nama; try { const r = await fetch("https://api.open-meteo.com/v1/forecast?latitude=" + c.lat + "&longitude=" + c.lon + "¤t=temperature_2m&timezone=auto"); if (!r.ok) throw new Error("http"); const j = await r.json(); const suhu = j && j.current ? j.current.temperature_2m : null; if (typeof suhu !== "number") throw new Error("data"); el.innerHTML = "🌡️ " + (Math.round(suhu * 10) / 10).toFixed(1).replace(".", ",") + "°C di " + esc(label); } catch (e) { el.innerHTML = `Suhu setempat tidak tersedia saat ini`; } } function initNow() { tickClock(); setInterval(tickClock, 1000); fetchTemp(); setInterval(fetchTemp, 60000); const wrap = $("#now-city-wrap"), sel = $("#now-city"); if (sel) sel.addEventListener("change", () => { nowCityKey = sel.value; fetchTemp(); }); const showCityPicker = () => { if (wrap) wrap.hidden = false; }; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( pos => { nowCoords = { lat: pos.coords.latitude, lon: pos.coords.longitude }; if (wrap) wrap.hidden = true; fetchTemp(); }, showCityPicker, { timeout: 8000, maximumAge: 600000 } ); } else showCityPicker(); } /* ================= Init ================= */ initNow(); renderHome(); initSaran(); bindDynamic(document); updateOnlineStatus(); if (isStandalone()) markInstalled(); $("#hero-search").addEventListener("input", heroSearchRun); $("#hero-search").addEventListener("focus", heroSearchRun); $("#hero-search-btn").addEventListener("click", async () => { const q = $("#hero-search").value.trim(); if (!q) { document.getElementById("semua-tools").scrollIntoView({ behavior: "smooth" }); return; } if (searchKodepos(q).length) { $("#search-results").hidden = true; openTool("kodepos", q); return; } const t = TOOLS.find(x => (x.name + " " + x.keys).toLowerCase().includes(q.toLowerCase())); $("#search-results").hidden = true; if (t) openTool(t.id); else document.getElementById("semua-tools").scrollIntoView({ behavior: "smooth" }); });