diff --git a/configure.ac b/configure.ac
index e154ac3a3..c044f53e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -472,6 +472,10 @@ fi
 
 MPD_DEFINE_CONDITIONAL(enable_icu, HAVE_ICU, [libicu])
 
+if test x$enable_icu != xyes; then
+	AC_CHECK_FUNCS(iconv)
+fi
+
 AC_ARG_ENABLE(glib,
 	AS_HELP_STRING([--enable-glib],
 		[enable GLib (default: auto)]),,
diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index 7e3871f70..b59a39e40 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -215,6 +215,9 @@ static void version(void)
 #ifdef USE_EPOLL
 	       " epoll"
 #endif
+#ifdef HAVE_ICONV
+	       " iconv"
+#endif
 #ifdef HAVE_ICU
 	       " icu"
 #endif
diff --git a/src/fs/Charset.hxx b/src/fs/Charset.hxx
index 9d119fea7..6ca5888e5 100644
--- a/src/fs/Charset.hxx
+++ b/src/fs/Charset.hxx
@@ -24,7 +24,7 @@
 #include "Compiler.h"
 #include "Traits.hxx"
 
-#if (defined(HAVE_ICU) || defined(HAVE_GLIB)) && !defined(WIN32)
+#if (defined(HAVE_ICU) || defined(HAVE_ICONV) || defined(HAVE_GLIB)) && !defined(WIN32)
 #define HAVE_FS_CHARSET
 #endif
 
diff --git a/src/lib/icu/Converter.cxx b/src/lib/icu/Converter.cxx
index 8f20813c4..72028c82e 100644
--- a/src/lib/icu/Converter.cxx
+++ b/src/lib/icu/Converter.cxx
@@ -31,6 +31,9 @@
 #ifdef HAVE_ICU
 #include "Util.hxx"
 #include <unicode/ucnv.h>
+#elif defined(HAVE_ICONV)
+#include "util/Domain.hxx"
+static constexpr Domain iconv_domain("iconv");
 #elif defined(HAVE_GLIB)
 #include "util/Domain.hxx"
 static constexpr Domain g_iconv_domain("g_iconv");
@@ -61,6 +64,20 @@ IcuConverter::Create(const char *charset, Error &error)
 	}
 
 	return new IcuConverter(converter);
+#elif defined(HAVE_ICONV)
+	iconv_t to = iconv_open("utf-8", charset);
+	iconv_t from = iconv_open(charset, "utf-8");
+	if (to == (iconv_t)-1 || from == (iconv_t)-1) {
+		error.FormatErrno("Failed to initialize charset '%s'",
+				  charset);
+		if (to != (iconv_t)-1)
+			iconv_close(to);
+		if (from != (iconv_t)-1)
+			iconv_close(from);
+		return nullptr;
+	}
+
+	return new IcuConverter(to, from);
 #elif defined(HAVE_GLIB)
 	GIConv to = g_iconv_open("utf-8", charset);
 	GIConv from = g_iconv_open(charset, "utf-8");
@@ -79,6 +96,26 @@ IcuConverter::Create(const char *charset, Error &error)
 }
 
 #ifdef HAVE_ICU
+#elif defined(HAVE_ICONV)
+
+static AllocatedString<char>
+DoConvert(iconv_t conv, const char *src)
+{
+	// TODO: dynamic buffer?
+	char buffer[4096];
+	char *in = const_cast<char *>(src);
+	char *out = buffer;
+	size_t in_left = strlen(src);
+	size_t out_left = sizeof(buffer);
+
+	size_t n = iconv(conv, &in, &in_left, &out, &out_left);
+
+	if (n == static_cast<size_t>(-1) || in_left > 0)
+		return nullptr;
+
+	return AllocatedString<>::Duplicate(buffer, sizeof(buffer) - out_left);
+}
+
 #elif defined(HAVE_GLIB)
 
 static AllocatedString<char>
@@ -123,7 +160,7 @@ IcuConverter::ToUTF8(const char *s) const
 
 	const size_t target_length = target - buffer;
 	return UCharToUTF8({buffer, target_length});
-#elif defined(HAVE_GLIB)
+#elif defined(HAVE_ICONV) || defined(HAVE_GLIB)
 	return DoConvert(to_utf8, s);
 #endif
 }
@@ -155,7 +192,7 @@ IcuConverter::FromUTF8(const char *s) const
 
 	return AllocatedString<>::Duplicate(buffer, target);
 
-#elif defined(HAVE_GLIB)
+#elif defined(HAVE_ICONV) || defined(HAVE_GLIB)
 	return DoConvert(from_utf8, s);
 #endif
 }
diff --git a/src/lib/icu/Converter.hxx b/src/lib/icu/Converter.hxx
index fd5ea2132..d7a9a2113 100644
--- a/src/lib/icu/Converter.hxx
+++ b/src/lib/icu/Converter.hxx
@@ -26,6 +26,9 @@
 #ifdef HAVE_ICU
 #include "thread/Mutex.hxx"
 #define HAVE_ICU_CONVERTER
+#elif defined(HAVE_ICONV)
+#include <iconv.h>
+#define HAVE_ICU_CONVERTER
 #elif defined(HAVE_GLIB)
 #include <glib.h>
 #define HAVE_ICU_CONVERTER
@@ -56,6 +59,11 @@ class IcuConverter {
 	UConverter *const converter;
 
 	IcuConverter(UConverter *_converter):converter(_converter) {}
+#elif defined(HAVE_ICONV)
+	const iconv_t to_utf8, from_utf8;
+
+	IcuConverter(iconv_t _to, iconv_t _from)
+		:to_utf8(_to), from_utf8(_from) {}
 #elif defined(HAVE_GLIB)
 	const GIConv to_utf8, from_utf8;
 
@@ -66,6 +74,11 @@ class IcuConverter {
 public:
 #ifdef HAVE_ICU
 	~IcuConverter();
+#elif defined(HAVE_ICONV)
+	~IcuConverter() {
+		iconv_close(to_utf8);
+		iconv_close(from_utf8);
+	}
 #elif defined(HAVE_GLIB)
 	~IcuConverter() {
 		g_iconv_close(to_utf8);