diff --git a/doc/src/geturl.rst b/doc/src/geturl.rst
new file mode 100644
index 0000000000..e75e5cd1bf
--- /dev/null
+++ b/doc/src/geturl.rst
@@ -0,0 +1,72 @@
+.. index:: geturl
+
+geturl command
+==============
+
+Syntax
+""""""
+
+.. code-block:: LAMMPS
+
+ geturl url keyword args ...
+
+* url = URL of the file to download
+* zero or more keyword argument pairs may be provided
+* keyword = *output* or *verify* or *overwrite*
+
+ .. parsed-literal::
+
+ *output* filename = write to *filename* instead of inferring the name from the URL
+ *verify* yes/no = verify SSL certificate and hostname if *yes*, do not if *no*
+ *overwrite* yes/no = if *yes* overwrite the output file in case it exists, do not if *no*
+
+Examples
+""""""""
+
+.. code-block:: LAMMPS
+
+ geturl https://www.ctcms.nist.gov/potentials/Download/1990--Ackland-G-J-Vitek-V--Cu/2/Cu2.eam.fs
+ geturl https://github.com/lammps/lammps/blob/develop/bench/in.lj output in.bench-lj
+
+Description
+"""""""""""
+
+Download a file from an URL to the local disk. This is implemented with
+the `libcurl library `_ which supports a
+large variety of protocols including "http", "https", "ftp", "scp",
+"sftp", "file". The transfer will only be performed on MPI rank 0.
+
+The *output* keyword can be used to set the filename. By default, the last part
+of the URL is used.
+
+The *verify* keyword allows to turn on or off whether ``libcurl`` will validate
+the SSL certificate and hostname for encrypted connections. Turning this off
+may be required when using a proxy or connecting to a server with a self-signed
+SSL certificate.
+
+The *overwrite* keyword determines whether a file should be overwritten if it
+already exists. If the argument is *no*, then the download will be skipped
+if the file exists.
+
+----------
+
+Restrictions
+""""""""""""
+
+This command is part of the EXTRA-COMMAND package. It is only enabled
+if LAMMPS was built with that package. See the :doc:`Build package
+` page for more info. It also requires that LAMMPS was
+built with support for `the libcurl library
+`_. See the page about :ref:`Compiling LAMMPS
+with libcurl support ` for further info. If support for
+libcurl is not included, using *geturl* will trigger an error.
+
+Related commands
+""""""""""""""""
+
+:doc:`shell `
+
+Default
+"""""""
+
+*verify* = yes, *overwrite* = yes
diff --git a/src/EXTRA-COMMAND/geturl.cpp b/src/EXTRA-COMMAND/geturl.cpp
new file mode 100644
index 0000000000..df46d0b723
--- /dev/null
+++ b/src/EXTRA-COMMAND/geturl.cpp
@@ -0,0 +1,111 @@
+/* ----------------------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ https://www.lammps.org/, Sandia National Laboratories
+ LAMMPS development team: developers@lammps.org
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+ Contributing authors: Axel Kohlmeyer (Temple U),
+------------------------------------------------------------------------- */
+
+#include "geturl.h"
+
+#include "comm.h"
+#include "error.h"
+
+#if defined(LAMMPS_CURL)
+#include
+#endif
+
+using namespace LAMMPS_NS;
+
+/* ---------------------------------------------------------------------- */
+
+void GetURL::command(int narg, char **arg)
+{
+#if !defined(LAMMPS_CURL)
+ error->all(FLERR, "LAMMPS has not been compiled with libcurl support");
+#else
+ if (narg < 1) utils::missing_cmd_args(FLERR, "geturl", error);
+ int verify = 1;
+ int overwrite = 1;
+
+ // process arguments
+
+ std::string url = arg[0];
+
+ // sanity check
+
+ if ((url.find(':') == std::string::npos) || (url.find('/') == std::string::npos))
+ error->all(FLERR, "URL '{}' is not a supported URL", url);
+
+ std::string output = url.substr(url.find_last_of('/') + 1);
+ if (output.empty()) error->all(FLERR, "URL '{}' must end in a file string", url);
+
+ int iarg = 1;
+ while (iarg < narg) {
+ if (strcmp(arg[iarg], "output") == 0) {
+ if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl output", error);
+ output = arg[iarg + 1];
+ ++iarg;
+ } else if (strcmp(arg[iarg], "overwrite") == 0) {
+ if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl overwrite", error);
+ overwrite = utils::logical(FLERR, arg[iarg + 1], false, lmp);
+ ++iarg;
+ } else if (strcmp(arg[iarg], "verify") == 0) {
+ if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl verify", error);
+ verify = utils::logical(FLERR, arg[iarg + 1], false, lmp);
+ ++iarg;
+ } else {
+ error->all(FLERR, "Unknown geturl keyword: {}", arg[iarg]);
+ }
+ ++iarg;
+ }
+
+ // only download files from rank 0
+
+ if (comm->me != 0) return;
+
+ if (!overwrite && platform::file_is_readable(output)) return;
+
+ // open output file for writing
+
+ FILE *out = fopen(output.c_str(), "wb");
+ if (!out)
+ error->all(FLERR, "Cannot open output file {} for writing: {}", output, utils::getsyserror());
+
+ // initialize curl and perform download
+
+ CURL *curl;
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+ curl = curl_easy_init();
+ if (curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) out);
+ curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
+ curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
+
+ if (!verify) {
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+ }
+ auto res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ long response = 0L;
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
+ error->one(FLERR, "Download of {} failed with: {} {}", output, curl_easy_strerror(res),
+ response);
+ }
+ curl_easy_cleanup(curl);
+ }
+ curl_global_cleanup();
+ fclose(out);
+#endif
+}
diff --git a/src/EXTRA-COMMAND/geturl.h b/src/EXTRA-COMMAND/geturl.h
new file mode 100644
index 0000000000..2f4cf8ccb3
--- /dev/null
+++ b/src/EXTRA-COMMAND/geturl.h
@@ -0,0 +1,34 @@
+/* -*- c++ -*- ----------------------------------------------------------
+ LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+ https://www.lammps.org/, Sandia National Laboratories
+ LAMMPS development team: developers@lammps.org
+
+ Copyright (2003) Sandia Corporation. Under the terms of Contract
+ DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+ certain rights in this software. This software is distributed under
+ the GNU General Public License.
+
+ See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef COMMAND_CLASS
+// clang-format off
+CommandStyle(geturl,GetURL);
+// clang-format on
+#else
+
+#ifndef LMP_GETURL_H
+#define LMP_GETURL_H
+
+#include "command.h"
+
+namespace LAMMPS_NS {
+
+class GetURL : public Command {
+ public:
+ GetURL(class LAMMPS *lmp) : Command(lmp) {};
+ void command(int, char **) override;
+};
+} // namespace LAMMPS_NS
+#endif
+#endif