diff --git a/check/checkconfigurations/checkconfigurations.go b/check/checkconfigurations/checkconfigurations.go
index 27a1ea49..9e896e3e 100644
--- a/check/checkconfigurations/checkconfigurations.go
+++ b/check/checkconfigurations/checkconfigurations.go
@@ -761,6 +761,21 @@ var configurations = []Type{
 		ErrorModes:      nil,
 		CheckFunction:   checkfunctions.LibraryPropertiesMisspelledOptionalField,
 	},
+	{
+		ProjectType:     projecttype.Library,
+		Category:        "structure",
+		Subcategory:     "",
+		ID:              "",
+		Brief:           "submodule",
+		Description:     "",
+		MessageTemplate: `Git submodule detected. Library Manager installations and installations from GitHub's "Download ZIP" will only contain an empty folder in place of the submodule.`,
+		DisableModes:    nil,
+		EnableModes:     []checkmode.Type{checkmode.All},
+		InfoModes:       nil,
+		WarningModes:    []checkmode.Type{checkmode.All},
+		ErrorModes:      nil,
+		CheckFunction:   checkfunctions.LibraryHasSubmodule,
+	},
 	{
 		ProjectType:     projecttype.Sketch,
 		Category:        "structure",
diff --git a/check/checkfunctions/library.go b/check/checkfunctions/library.go
index 8ff945da..7e750566 100644
--- a/check/checkfunctions/library.go
+++ b/check/checkfunctions/library.go
@@ -785,6 +785,21 @@ func LibraryPropertiesMisspelledOptionalField() (result checkresult.Type, output
 	return checkresult.Pass, ""
 }
 
+// LibraryHasSubmodule checks whether the library contains a Git submodule.
+func LibraryHasSubmodule() (result checkresult.Type, output string) {
+	dotGitmodulesPath := checkdata.ProjectPath().Join(".gitmodules")
+	hasDotGitmodules, err := dotGitmodulesPath.ExistCheck()
+	if err != nil {
+		panic(err)
+	}
+
+	if hasDotGitmodules && dotGitmodulesPath.IsNotDir() {
+		return checkresult.Fail, ""
+	}
+
+	return checkresult.Pass, ""
+}
+
 // spellCheckLibraryPropertiesFieldValue returns the value of the provided library.properties field with commonly misspelled words corrected.
 func spellCheckLibraryPropertiesFieldValue(fieldName string) (result checkresult.Type, output string) {
 	if checkdata.LibraryPropertiesLoadError() != nil {
diff --git a/check/checkfunctions/library_test.go b/check/checkfunctions/library_test.go
index 980bd1d6..b3feece0 100644
--- a/check/checkfunctions/library_test.go
+++ b/check/checkfunctions/library_test.go
@@ -170,3 +170,12 @@ func TestLibraryPropertiesPrecompiledFieldEnabledWithFlatLayout(t *testing.T) {
 
 	checkCheckFunction(LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout, testTables, t)
 }
+
+func TestLibraryHasSubmodule(t *testing.T) {
+	testTables := []checkFunctionTestTable{
+		{"Has submodule", "Submodule", checkresult.Fail, ""},
+		{"No submodule", "Recursive", checkresult.Pass, ""},
+	}
+
+	checkCheckFunction(LibraryHasSubmodule, testTables, t)
+}
diff --git a/check/checkfunctions/testdata/libraries/Submodule/.gitmodules b/check/checkfunctions/testdata/libraries/Submodule/.gitmodules
new file mode 100644
index 00000000..61cbeaba
--- /dev/null
+++ b/check/checkfunctions/testdata/libraries/Submodule/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "foo"]
+	path = foo
+	url = https://example.com/foo.git
diff --git a/check/checkfunctions/testdata/libraries/Submodule/library.properties b/check/checkfunctions/testdata/libraries/Submodule/library.properties
new file mode 100644
index 00000000..9adb6237
--- /dev/null
+++ b/check/checkfunctions/testdata/libraries/Submodule/library.properties
@@ -0,0 +1,9 @@
+name=Submodule
+version=1.0.0
+author=Cristian Maglie <c.maglie@example.com>, Pippo Pluto <pippo@example.com>
+maintainer=Cristian Maglie <c.maglie@example.com>
+sentence=A library that makes coding a web server a breeze.
+paragraph=Supports HTTP1.1 and you can do GET and POST.
+category=Communication
+url=http://example.com/
+architectures=avr
diff --git a/check/checkfunctions/testdata/libraries/Submodule/src/Submodule.h b/check/checkfunctions/testdata/libraries/Submodule/src/Submodule.h
new file mode 100644
index 00000000..e69de29b